共変・反変・双変

Recent posts

変性

共変・反変・双変・不変のいずれかを指す。

共変(covariance)

型そのもの、もしくはサブタイプを許容する。

TSでは関数の引数がこの変性を持つ。

class Animal { a(){} }
class Dog extends Animal { b(){} }
class Shiba extends Dog { c(){} }

function fn<T extends Dog>(arg: T) {}

fn(new Animal()); // スーパー ❌
fn(new Dog()); // 型が一致 ✅
fn(new Shiba()); // サブ ✅

反変(contravariance)

型そのもの、もしくはスーパータイプを割り当てることができる。

双変(bivariance)

型そのもの・サブタイプ・スーパータイプを許容する。

TSではstrictFunctionChecksをfalseにすると、Typeで宣言した関数の引数がこの変性を持つ。

strict: false, // strictはstrictFunctionChecks:trueにセットする
strictFunctionChecks: false,
class Animal { a(){} }
class Dog extends Animal { b(){} }
class Shiba extends Dog { c(){} }

type Fn = (arg: Dog) => void;

const fn1 = (x:Animal) => {}; // スーパー ✅
const fn2 = (x:Dog) => {}; // 型が一致 ✅
const fn3 = (x:Shiba) => {}; // サブ ✅

functionやconstでの関数宣言では双変にならなかった。Typeと扱いが違うらしい。

function fn(arg: Dog) {}
// const fn = (arg: Dog) => {}; これでも同じ結果

fn(new Animai()); // スーパー ❌
fn(new Dog());
fn(new Shiba());

不変(invariant)

型そのものを許容する。サブタイプ・スーパータイプは許容しない。