在 TS 的语句中,语句右边类型是语句左边类型的子类型时,才不会报错。
在一般类型中,这很清楚,例如:
// 无报错
const value1: string | number = undefined as string
// 有报错
// Type 'string | number | boolean' is not assignable to type 'string | number'.
// 因为右边不是左边的子类型,多了一个 boolean
const value2: string | number = undefined as string | number | boolean
下面考虑 function 类型。function 可以抽象为 P->R
的类型。
通用的规则是:对你接受的东西要宽松,对你产生的东西要保守。be liberal in what you accept and conservative in what you produce.
数学描述是:当 P2 >= P2
,且 R2 <= R1
时,才有 (P1->R1) <= (P2->R2)
。
例如:
// P2>P1, R2<R1 满足
const function1: (p: string | number) => string | number = undefined as (p: string | number | boolean) => string
// P2<P1,R2=R1 不满足
const function2: (p: string | number) => string | number = undefined as (p: string) => string | number
// P2=P1, R2>R1 不满足
const function3: (p: string | number) => string | number = undefined as (p: string | number) => string | number | boolean
参考资料
- 关于 function 子类型的 issue https://github.com/microsoft/TypeScript/issues/42582
- 类型系统设计 https://en.wikipedia.org/wiki/Covarianceand_contravariance(computer_science)#Function_types#Function_types)