TypeScript是一种静态类型的编程语言,它提供了一些高级类型工具,如条件类型和infer关键字,使得类型系统更加灵活和强大。本章节将重点介绍条件类型和infer关键字在TypeScript中的使用,并通过代码示例演示它们的具体应用。
1、条件类型
条件类型是一种可以根据类型关系条件性地选择另一种类型的工具。它通常用于泛型类型的约束,以根据泛型类型的具体类型参数来选择不同的类型。
基本语法
条件类型的基本语法如下:
T extends U ? X : Y
其中,T和U是两种类型,X和Y是两种备选类型。当T可以赋值给U时,条件类型的值为X,否则为Y。
示例
我们来看一个简单的例子,实现一个泛型函数trim,将字符串去除两端的空格。如果参数是字符串类型,则直接调用trim()方法;如果是其他类型,则返回原值。
type IsString<T> = T extends string ? true : false;
function trim<T extends string | number>(value: T): IsString<T> extends true ? string : T {
return typeof value === 'string' ? value.trim() : value;
}
console.log(trim(' hello ')); // 'hello'
console.log(trim(123)); // 123
在上面的代码中,我们定义了一个条件类型IsString
在trim函数中,我们使用了泛型类型T extends string | number来约束参数的类型。接着使用了条件类型,当IsString
嵌套条件类型
条件类型可以进行嵌套,以实现更加复杂的类型逻辑。
type NonNullable<T> = T extends null | undefined ? never : T;
type Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;
type MyType = { a?: number[], b: string } | null;
type MyTypeWithoutNull = NonNullable<MyType>;
type MyTypeFlatten = Flatten<MyType>;
// MyTypeWithoutNull 的类型为 { a?: number[], b: string }
// MyTypeFlatten 的类型为 number | string
在上面的例子中,我们定义了两个条件类型。NonNullable
我们还定义了一个复杂的类型MyType,它可以是一个MyType类型为{ a?: number[], b: string }或null类型。我们使用NonNullable
2、infer关键字
infer是TypeScript 2.8版本中引入的一个新关键字,用于推断类型变量的类型。它通常用于条件类型的右侧,以获取泛型类型的具体类型参数。
基本语法
infer的基本语法如下:
T extends (infer U)[] ? U : never
其中,T extends (infer U)[]表示T是一个数组类型,并将数组元素类型赋值给类型变量U。U即为要推断的类型变量,可以在条件类型的其他地方使用。如果T不是数组类型,则返回never类型。
示例
我们来看一个示例,实现一个泛型函数head,返回数组的第一个元素。我们使用infer关键字来获取数组元素的类型。
function head<T extends any[]>(arr: T): T extends [infer U, ...any[]] ? U : never {
return arr[0];
}
const arr1 = [1, 2, 3];
const arr2 = ['a', 'b', 'c'];
const arr3 = [];
console.log(head(arr1)); // 1
console.log(head(arr2)); // 'a'
console.log(head(arr3)); // never
在上面的代码中,我们使用泛型类型T extends any[]来约束参数的类型,表示参数必须是一个数组类型。接着使用条件类型T extends [infer U, …any[]] ? U : never,表示当T是一个非空数组类型时,返回数组第一个元素的类型;否则返回never类型。在条件类型中,我们使用了infer关键字来获取数组元素的类型。
通过上面的示例,我们可以看到,infer关键字可以方便地获取泛型类型的具体类型参数,使得类型系统更加灵活和强大。
小结
本文介绍了TypeScript中的条件类型和infer关键字,以及它们的基本语法和应用场景。通过使用这些高级类型工具,我们可以更加方便地实现复杂的类型逻辑,提高代码的可读性和可维护性。