TS 高级

182 阅读2分钟

typeof

typeof 类型查询,用于获取一个变量的类型

const defaultOption = {
  timeout: 400
}
type Opt = typeof defaultOption

❌ 错的:

const s = "hello"
type myType = typeof s

TypeScript 中,常量具有字面量类型,也就是它们的实际值。实际 myType 的是 "hello",而不是 string 类型。

keyof

keyof 用于获取 interface 或 type 定义的类型的 key

interface Point{
  x: number;
  y: number;
}

// type keys = "x" | "y"
type keys = keyof Point

如果想获取某个变量的 key 的类型定义,需要先使用 typeof 转换一下:

const obj = {
  name: 'a',
  age: 100
}

type k1 = keyof typeof obj

Partial Required Pick

interface User{
  id: number;
  name: string;
  age: number;
}
type PartialUser = Partial<User>
type RequiredUser = Required<User>
type PickUser = Pick<User, 'id' | 'name'>

Pick Omit

interface User{
  id: number;
  name?: string;
  age?: number;
}

type PickUser = Pick<User, 'id' | 'name'>
type OmitUser = Omit<User, 'name'>
// 等价
type PickUser = {  
   id: number;  
   name?: string | undefined;  
}

type OmitUser = {  
  id: number;  
  age?: number | undefined;  
}

Extract Exclude

type T1 = Extract<'a' | 'b' | 'c', 'a' | 'b' | 'f'>
type T2 = Exclude<'a' | 'b' | 'c', 'a' | 'b' | 'f'>
// 等价于
type T1 = "a" | "b"
type T2 = "c"

Exclude Omit

Exclude 从联合类型里面排除一个或几个
Omit 从interface 或 type 定义的类型里面排除一个或几个属性

// type AC = 'A' | 'C'
type ABC = 'A' | 'B' | 'C'
type AC = Exclude<ABC, 'B'>

interface User{
  id: number;
  name: string;
  age: number;
}
type UId = Omit<User, 'name' | 'age'>

infer ReturnType Parameters

通过 infer 可以类型推导出函数参数及返回值类型,infer 只能用于 extends 语句。

function foo(a: string){
  return 1
}
type FnReturn = ReturnType<typeof foo>
type FnParam = Parameters<typeof foo>

Record interface type

定义某些类型

type RecordA = Record<string, string>
const a: RecordA = {a: '', b: 'd'}

跟 enum 结合

enum Color{
  Red,
  Green,
}
type RecordColor = Record<Color, string>
const rc: RecordColor = {
  [Color.Red]: '',
  [Color.Green]: 'g',
} // 必须写全

VS interface

interface RecordA{
  [k: string]: string
}

但是 interface 的 key 不能直接使用枚举类型:

interface ColorToString{
  [k: Color]: string
}

An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead.

意思是 interface 的键类型只能是 string 或 number,不能直接使用枚举类型

interface ColorToString{
  [k in Color]: string
}

A mapped type may not declare properties or methods

意思是处理映射类型不能使用 interface, 应该使用 type

type ColorToString = {
  [k in Color]: string
}

const ct: CToStr = {
  [Color.Red]: 'g',
  [Color.Green]: 'g',
}

定义函数

1.  函数声明

function add(x: number, y: number): number{
  return x+y
}

2.  函数表达式

const add: (x: number, y: number) => number = function(a,b){
  return a+b
}

3.  接口

interface AddFn{
  (x: number, y: number): number;
}

4.  类型别名

type AddFn = (x: number, y: number) => number

unknown any

unknown 类型变量是不知道的类型,使用的时候需要先判断一下变量的类型。 any 是任意类型,告诉编辑器不用考虑该变量的类型,可以直接使用变量的属性或方法。

typescript 高级技巧 | 山月行