开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情
索引访问类型
在 TypeScript 中,我们可以通过按名称查找属性来访问它的类型:
type AppConfig = {
username: string;
layout: string;
};
type Username = AppConfig["username"];
在这个例子中,通过 AppConfig 类型的索引 username 获取到其类型 string,类似于在 JavaScript 中通过索引来获取对象的属性值。
索引签名
当类型属性的实际名称是未知的,但它们将引用的数据类型已知时,索引签名就很方便。
type User = {
name: string;
preferences: {
[key: string]: string;
}
};
const currentUser: User = {
name: 'Foo Bar',
preferences: {
lang: 'en',
},
};
const currentLang = currentUser.preferences.lang;
在上面的例子中,currentLang 的类型是 string 而不是 any。此功能与 keyof 运算符一起搭配使用是使映射类型成为可能的核心之一。
联合类型
联合类型是两种或多种类型的组合。它表明值的类型可以是联合中包含的任何一种类型。
type StringOrNumberUnion = string | number;
let value: StringOrNumberUnion = 'hello, world!';
value = 100;
下面是一个更复杂的例子,编译器可以为联合类型提供一些高级保护:
type Animal = {
name: string;
species: string;
};
type Person = {
name: string;
age: number;
};
type AnimalOrPerson = Animal | Person;
const value: AnimalOrPerson = loadFromSomewhereElse();
console.log(value.name); // ✅
console.log(value.age); // ❌
if ('age' in value) {
console.log(value.age); // ✅
}
在这个例子中,因为 Animal 和 Person 都有 name 属性,所以 value.name 可以正常输出,没有错误。而 value.age 会编译错误,因为如果 value 是 Animal 类型,则 value 是没有 age 属性的。在 if 块中,因为只有 value 存在 age 属性才能进入这个代码块。所以,在这个 if 块中,value 一定是 Person,TS 可以知道 value 一定是具有 age 属性的,所以编译正确。
keyof 类型运算符
keyof 类型运算符返回传递给它的类型的 key 的联合。
type AppConfig = {
username: string;
layout: string;
};
type AppConfigKey = keyof AppConfig;
在这个例子中,AppConfigKey 类型会被解析为 "username" | "layout"。它可以与索引签名一起使用:
type User = {
name: string;
preferences: {
[key: string]: string;
}
};
type UserPreferenceKey = keyof User["preferences"];
这里,UserPreferenceKey 类型被解析为 string | number。
元组类型
元组是一种特殊的数组类型,其中数组的元素可能是特定索引处的特定类型。它们允许 TypeScript 编译器围绕值数组提供更高的安全性,尤其是当这些值属于不同类型时。
例如,TypeScript 编译器能够为元组的各种元素提供类型安全:
type Currency = [number, string];
const amount: Currency = [100, 'USD'];
function add(values: number[]) {
return values.reduce((a, b) => a + b);
}
add(amount);
// Error: Argument of type 'Currency' is not assignable to parameter of type 'number[]'.
// Type 'string' is not assignable to type 'number'.
上面的代码中会报错,Currency 类型的参数不能分配给“number[]”类型的参数,string 类型不能分配给 number 类型。
当访问超出元组定义类型的索引处的元素时,TypeScript 能够进行提示:
type LatLong = [number, number];
const loc: LatLong = [48.858370, 2.294481];
console.log(loc[2]);
// Error: Tuple type 'LatLong' of length '2' has no element at index '2'.
这里,元组类型 LatLong 只有两个元素,当试图访问第三个元素时,就会报错。
条件类型
条件类型是一个表达式,类似于 JavaScript 中的三元表达式,其语法如下:
T extends U ? X : Y
来看一个实际的例子:
type ConditionalType = string extends boolean ? string : boolean;
在上面的示例中,ConditionalType 的类型将是 boolean,因为条件string extends boolean 是始终为 false。