关键字在 TypeScript 中具有特定的含义,用于定义类型、类、接口、函数等。例如,number、string、boolean 是 TypeScript 中的关键字,用于声明基本类型。同时,还有其他关键字如 interface、class、enum、function 、extends、in、keyof 和 typeof 等等。

基础的类型这里不展开讲,我们来说下其他比较特殊的关键字用法。

extends

extends 顾名思义就是继承,常用的场景有类型继承、条件类型、类型约束

类型继承

类型继承指的是一种类型之间的关系,其中一个类型(称为子类型)可以继承另一个类型(称为父类型)的属性和方法。通过类型继承,可以创建更复杂的类型层次结构,便于重用代码和定义更具体的行为。

interface People {
  name: string;
  age: number;
}
const people: People = {
  name: "Kelen",
  age: 25,
};
interface Developer extends People {
  skills: string[];
}
const developer: Developer = {
  name: "Kelen",
  age: 25,
  skills: ["Javascript", "Typescript"],
};

条件类型

使用 extends 关键字可以根据给定的类型条件来确定最终的类型。

// 如果 T 可以满足类型 Person 则返回 Person 类型,否则为 T 类型
type IsPerson<T> = T extends Person ? Person : T;    

类型约束

类型约束是一种在类型系统中进行条件判断的机制,用于判断一个类型是否符合某些条件。

type People = {
  name: string,
  age: number,
}

function getAttr<T extends People>(people: T) {
  return people.name
}

// 报错 Property 'age' is missing in type '{ name: string; }' but required in type 'People'
getAttr({ name: "kelen" })

// 下面都是可以的
getAttr({ name: "kelen", age: 12 })
getAttr({ name: 'kelen', age: 12, height: 20 })

keyof操作符

使用 keyof 操作符可以获取一个对象类型的所有 key 或 数字字面量组合的联合类型。

type Person = {
  name: string
  age: number
  heigh: number
  weigh: number
}

type Keys = keyof Person // 'name' | 'age' | 'heigh' | 'weigh'

typeof操作符

typeof 主要用于对类型上下文进行判断,可以使用 typeof 创建一个新的类型。

const name: string = 'kelen'
const name2: typeof name = 'kelen2' // 相当于 const name2: string = 'kelen2'

const person = {
  name: name,
  age: 18
}

type Person = typeof person

const person2: Person = {
  name: name2,
  age: 18
}

infer关键字

TypeScript 中的 infer 关键字用于在类型推断中提取类型。它可以方便地从一个类型中提取出一个新的类型,这样就可以在类型谓词中使用这个新的类型了。

使用 infer 关键字可以在类型推断中提取出某个类型,这样可以在不显式指定类型的情况下让 TypeScript 自动推断出正确的类型,提高代码的可读性和可维护性。比如提取函数返回值的类型。

type GetReturnType<T> = T extends (...args: never[]) => infer Return ? Return : never 
type Num = GetReturnType<() => number> // number
type Str = GetReturnType<(x: string) => string> // string
type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]> // boolean[]