类型别名

  • type用于定义类型别名
// 联合类型
type IDType = string | number | boolean
// 对象类型
type PointType = {
x: number
y: number
z?: number
}
// 函数类型
type Handler = (e: Event) => void;

const clickHandler: Handler = (e) => { };
const moveHandler: Handler = (e) => { };
const dragHandler: Handler = (e) => { };

function printId(id: IDType) {}
function printPoint(point: PointType) {}
  • 工具类型
    • 类型别名可以这么声明自己能够接受泛型(我称之为泛型坑位)
    • 泛型参数的名称(上面的 T )也不是固定的。通常我们使用大写的 T / K / U / V / M / O …这种形式。
    • 对于工具类型来说,它的主要意义是基于传入的泛型进行各种类型操作,得到一个新的类型
type Factory<T> = T | number | string;
// 一般不会直接使用工具类型来做类型标注,而是再度声明一个新的类型别名:
type FactoryWithBool = Factory<boolean>;
const foo: FactoryWithBool = true;

联合类型|与交叉类型&

  • 联合类型只需要符合成员之一即可(||),而交叉类型需要严格符合每一位成员(&&)。
interface NameStruct {
name: string;
}
interface AgeStruct {
age: number;
}

type ProfileStruct = NameStruct & AgeStruct;
const profile: ProfileStruct = {
name: "linbudu",
age: 18
}

// 新的类型会同时符合交叉类型的所有成员,不存在既是 string 又是 number 的类型
// 这也是 never 这一 BottomType 的实际意义之一,描述根本不存在的类型
type StrAndNum = string & number; // never
  • 对于对象类型的交叉类型,其内部的同名属性类型同样会按照交叉类型进行合并
type Struct1 = {
primitiveProp: string;
objectProp: {
name: string;
}
}

type Struct2 = {
primitiveProp: number;
objectProp: {
age: number;
}
}

type Composed = Struct1 & Struct2;

type PrimitivePropType = Composed['primitiveProp']; // never
type ObjectPropType = Composed['objectProp']; // { name: string; age: number; }

索引类型

  • 包含三个部分:索引签名类型索引类型查询索引类型访问

索引签名类型

  • 如下格式:
interface A {
[key: string]: string
}

索引类型查询

  • keyof操作符,返回索引所有key对应类型字面量的联合类型
    • 这里并不会将数字类型的键名转换为字符串类型字面量,而是仍然保持为数字类型字面量
interface Foo {
Kylin: 1,
599: 2
}

type FooKeys = keyof Foo; // "Kylin" | 599
// 在 VS Code 中悬浮鼠标只能看到 'keyof Foo'
// 看不到其中的实际值,你可以这么做:
type FooKeys = keyof Foo & {}; // "Kylin" | 599
  • 模拟 “从键名到联合类型” 的过程。
type FooKeys = Object.keys(Foo).join(" | ");
export const SIZES = ['mini', 'small', 'medium', 'large'] as const;
export type Size = typeof SIZES[number];
  • 这段代码定义了一个常量数组 SIZES,其中包含了四个字符串元素:minismallmediumlarge。同时,使用 as const 关键字将数组中的元素类型设为不可变常量类型。
  • 接下来,定义了一个类型别名 Size,它的类型是 typeof SIZES[number]。这个类型别名的意思是,Size 的类型是 SIZES 数组中所有元素的联合类型。[number] 表示数组的索引类型,typeof 表示获取 SIZES 的类型,因此 typeof SIZES[number] 表示获取 SIZES 数组中所有元素的类型,并将它们组成一个联合类型

img

img

映射类型

  • 映射类型只能使用类型别名实现
  • in是遍历的意思

image-20231221142535166

type Stringify<T> = {
[K in keyof T]: string;
};
  • [K in keyof T]: string是一个映射类型(Mapped Type)的语法。这个特定的映射类型 Stringify<T> 会将一个类型 T 的所有属性的类型转换成 string 类型
interface Foo {
prop1: string;
prop2: number;
prop3: boolean;
prop4: () => void;
}

type StringifiedFoo = Stringify<Foo>;

// 等价于
interface StringifiedFoo {
prop1: string;
prop2: string;
prop3: string;
prop4: string;
}