TypeScript 中的 5 种类型

86 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

索引访问类型

在 TypeScript 中,我们可以通过按名称查找属性来访问它的类型:

type AppConfig = {
  usernamestring;
  layoutstring;
};

type Username = AppConfig["username"];

在这个例子中,通过 AppConfig 类型的索引 username 获取到其类型 string,类似于在 JavaScript 中通过索引来获取对象的属性值。

索引签名

当类型属性的实际名称是未知的,但它们将引用的数据类型已知时,索引签名就很方便。

type User = {
  namestring;
  preferences: {
    [keystring]: string;
  }
};

const currentUserUser = {
  name'Foo Bar',
  preferences: {
    lang'en',
  },
};
const currentLang = currentUser.preferences.lang;

在上面的例子中,currentLang 的类型是 string 而不是 any。此功能与 keyof 运算符一起搭配使用是使映射类型成为可能的核心之一。

联合类型

联合类型是两种或多种类型的组合。它表明值的类型可以是联合中包含的任何一种类型。

type StringOrNumberUnion = string | number;

let valueStringOrNumberUnion = 'hello, world!';
value = 100;

下面是一个更复杂的例子,编译器可以为联合类型提供一些高级保护:

type Animal = {
  namestring;
  speciesstring;
};

type Person = {
  namestring;
  agenumber;
};

type AnimalOrPerson = Animal | Person;

const valueAnimalOrPerson = 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 = {
  usernamestring;
  layoutstring;
};

type AppConfigKey = keyof AppConfig;

在这个例子中,AppConfigKey 类型会被解析为 "username" | "layout"。它可以与索引签名一起使用:

type User = {
  namestring;
  preferences: {
    [keystring]: string;
  }
};

type UserPreferenceKey = keyof User["preferences"];

这里,UserPreferenceKey 类型被解析为 string | number

元组类型

元组是一种特殊的数组类型,其中数组的元素可能是特定索引处的特定类型。它们允许 TypeScript 编译器围绕值数组提供更高的安全性,尤其是当这些值属于不同类型时。

例如,TypeScript 编译器能够为元组的各种元素提供类型安全:

type Currency = [numberstring];

const amountCurrency = [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 = [numbernumber]; 

const locLatLong = [48.8583702.294481];

console.log(loc[2]);
// Error: Tuple type 'LatLong' of length '2' has no element at index '2'.

这里,元组类型 LatLong 只有两个元素,当试图访问第三个元素时,就会报错。

条件类型

条件类型是一个表达式,类似于 JavaScript 中的三元表达式,其语法如下:

extends U ? X : Y

来看一个实际的例子:

type ConditionalType = string extends boolean ? string : boolean;

在上面的示例中,ConditionalType 的类型将是 boolean,因为条件string extends boolean 是始终为 false。