TypeScript中常见关键字和工具类型

165 阅读3分钟

declare, declare global

  • declare定义全局变量、全局函数、全局命名空间、js modules、 class 等

  • declare global为全局对象window增加新的属性,否则读写window.xxx会校验失败报错。

declare global {
    interface Window {
    csrf: string;
    }
}

window.csrf = 'xxxxxxxxxxxx'

public、private、protected、readonly、abstract

  • public 默认值,公开的,可以被外部访问
  • private 私有的,类内部访问
  • protected 受保护的,类内部,以及类子类访问
  • readonly 属性设置为只读,只读属性必须在声明时或者构造函数里被初始化
  • abstract: 表示类或方法是抽象的,不能直接实例化,可以被扩展。

keyof和typeof

  • keyof索引类型查询操作符获取索引类型属性名构成联合类型
    • keyof 可以获取一个对象接口的所有 key值
  • typeof获取一个变量或者对象的类型
type obj = { a: string; b: string }
type Foo = keyof obj;
// type Foo = 'a' | 'b';
const obj = { a: '1' };
type Foo = typeof obj; 
// type Foo = { a: string }
enum A{
  A,B,C,D,E,F,G,H
}
type unionType = keyof typeof A; // 'A' | 'B'| 'C'

Pick、Record、Exclude、Partial、Omit、Merge、Intersection、Overwrite、ReturnType、Required、Partial、DeepPartial、Readonly、Mutable

  • Exclude<T,U> 从T中排除可分配给U的元素
  • Pick 用于在定义好的类型中取出特性的类型
  • Omit<T,K> 忽略T中某些元素
  • Merge<01, 02> 将两个对象属性合并
  • Overwrite<T,U> 用U中属性覆盖T中属性
  • Record 可以获得根据 K 中所有可能值来设置 key 以及 value 的类型
  • Partial 功能是将类型的属性变成可选
  • Required 功能与Partial相反,将类型的属性变成必选
  • Intersection<T,U> 取T的属性此属性也同样存在于U
  • ReturnType ReturnType 用来获取函数的返回值的类型
  • Readonly 将类型字段的值修改为只读属性,禁止修改
  • Mutable 功能是将类型的属性变成可修改,意思就是去除只读
  • Record 可以获得根据 K 中所有可能值来设置 key 以及 value 的类型
interface UserInfo {
  id: string;
  name: string;
}
type NewUserInfo = Pick<UserInfo, 'name'>; // {name: string;}
interface UserInfo {
  id: string;
  name: string;
}
type CurRecord = Record<'a' | 'b' | 'c', UserInfo>; // { a: UserInfo; b: UserInfo; c: UserInfo; }
type Func = (value: number) => string;
const foo: ReturnType<Func> = "1";
interface UserInfo {
    id: string
    name: string
}
// bad
const machinist: UserInfo = {
    name: 'machinist'
} 
// error 类型 "{ name: string; }" 中缺少属性 "id",但类型 "UserInfo" 中需要该属性。ts(2741)

type NewUserInfo = Partial<UserInfo>;
// good
const machinist: UserInfo = {
    name: 'machinist'
}
interface UserInfo {
  id?: string
  name?: string
}
type newUserInfo =  Required<UserInfo>
const machinist: newUserInfo = {
 id:"111"
}
// error 类型 "{ id: string; }" 中缺少属性 "name",但类型 "Required<UserInfo>" 中需要该属性。ts(2741)

type、interface

type 类型别名 用于给类型起一个新名字

type Value: string = "111"
// 或
type Iprops = {
  value: string,
  getName: () => string
}

interface 接口 用于声明类型

interface MyInterface {
  value: string,
  getName: () => string
}

type 和 interface的区别

  • type可以定义单个变量类型、联合类型、对象,interface只能定义对象;

  • type不可以重复声明,interface可以重复声明(声明合并);

type Iprops = {
    name: string
    age: number
}
type Iprops:string = "111" // Error 标识符“Iprops”重复。ts(2300)

interface MyInterface {
    name: string
    age: number
}
interface MyInterface {
    gender: string
}
const obj: MyInterface= {
    name: "string"
    age: 18,
    gender: "男",
}
// 重复声明相当于把两个类型加一块

注意: 重复声明同字段若类型不同也会报错

interface MyInterface {
    name: string
    age: number
}
interface MyInterface {
    age: string // 后续属性声明必须属于同一类型。属性“age”的类型必须为“number”,但此处却为类型“string”。ts(2717)
    gender: string
}
  • 两者的拓展
    请注意接口和类型别名不是互斥的。接口可以扩展类型别名,反之亦然。
// interface
interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }

// type
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };

infer

infer用于提取属性,具体的返回类型是依据三元表达式的返回而定。

type myInter<T> = T extends Array<infer U> ? U : T

extends、implements

  • extends用于接口与接口、类与类、接口与类之间的继承
  • implements用于类与类、类与接口之间的实现
    注意: extends类似于es6的extends,implements没有继承效果的,但是要求子类上必须需有父类的属性和方法,更倾向于限制子类的结构!

其他补充:数组定义的两种方式

type Foo = Array<string>
interface Bar {
    baz: Array<{ name: string, age: number }>;
}
type Foo = string[]
interface Bar {
    baz: { name :string, age: number }[];
}