Type Systems, Covariance, Contravariance, Bivariance, and Invariance

Programming

Posted by jopemachine on November 17, 2021 Updated on September 25, 2022

Type Systems: Covariance, Contravariance, Bivariance, and Invariance

Invariance

1
2
3
4
function method(value: Invariant<City>) {...}
method(new Noun());         // error...
method(new City());         // okay
method(new SanFrancisco()); // error...
  • Invariance는 딱 해당 객체만 허용한다. 해당 객체의 Superset, Subset들은 거절된다.

Covariance

1
2
3
4
function method(value: Covariant<City>) {...}
method(new Noun());         // error...
method(new City());         // okay
method(new SanFrancisco()); // okay
  • Covariance는 해당 객체의 Subset을 허용해준다.

Contravariance

1
2
3
4
function method(value: Contravariant<City>) {...}
method(new Noun());         // okay
method(new City());         // okay
method(new SanFrancisco()); // error...
  • Contravariance는 반대로 객체의 Superset을 허용해준다.

Bivariance

1
2
3
4
function method(value: Bivariant<City>) {...}
method(new Noun());         // okay
method(new City());         // okay
method(new SanFrancisco()); // okay
  • Bivariance는 객체의 Superset, Subset을 모두 허용한다.

하위 클래스들의 타입 변화

Good

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Equally specific inputs and outputs — Good
class SubClass extends BaseClass {
  method(value: City): City { ... }
}

// More specific outputs — Good
class SubClass extends BaseClass {
  method(value: City): SanFrancisco { ... }
}

// Less specific inputs — Good
class SubClass extends BaseClass {
  method(value: Noun): City { ... }
}

Bad

1
2
3
4
5
6
7
8
9
// Less specific outputs — Bad
class SubClass extends BaseClass {
  method(value: City): Noun { ... } // ERROR!!
}

// More specific inputs — Bad
class SubClass extends BaseClass {
  method(value: SanFrancisco): City { ... } // ERROR!!
}

원문