Typescript学习第二十四天

132 阅读2分钟

这是我参与2022首次更文挑战的第38天,活动详情查看:2022首次更文挑战

函数参数类型

编译器检查函数参数类型有非严格函数类型检查模式和严格函数类型检查模式两种检查模式。在非严格模式下,函数参数类型与函数类型时双变关系。当函数类型X是函数类型Y的子类型,那么X的参数类型必须是Y中对应参数类型的子类型或者超类型。严格模式下函数参数类型与函数类型时逆变关系,而不是相对宽松的双变关系。

type X = (a: 5 | 6) => void;
type Y = (x: number) => void;

对象类型

对象类型有0个或多个类型成员组成。对象类型间的子类型关系取决于对象的结果。对象类型的名称完全不影响对象类型间的子类型关系。当对象类型X时对象Y的子类型,那么Y中的必选属性成员在X中也必须是必选属性成员。如果两个类类型之间的子类型关系时仅检查类的实例成员类型,那么类的静态成员类型以及构造函数类型不进行检查。

interface X {
    h: string
}
interface Y {
    h: 'zss',
    s: 't'
}

泛型

实例化泛型类型时使用的实际类型参数不影响子类型关系,真正影响子类型关系的是泛型实例化后的结果对象类型。泛型函数类型也分为非严格泛型函数类型检查和严格泛型函数类型检查。在非严格泛型函数类型检查模式下,所有的泛型类型参数会被替换为any类型,然后再去确定子类型关系。严格泛型函数类型检查模式下,不会使用any类型去替换所有的类型参数,会先通过类型推断统一两个泛型函数的类型参数,再进行确认两者关系,这就是两个模式的区别。

type X = <T, U>(x: T, y: U) => [T, U];
type Y = <S>(x: S, y: S) => [S, S];

联合和交叉类型

联合类型语法X = X0 | X1和任意类型T,而交叉类型和联合类型语法区别就是将|修改为&。在联合类型中,如果类型T是成员类型X0的子类型或者类型T是成员X1的子类型,那么类型T是联合类型X的子类型。相反如果X0是T的子类型并且成员类型X0是类型T的子类型,那么联合类型X是类型T的子类型。交叉类型也是如此。

type X = 6 | 7;
type T = number;