ts

TypeScript

一些 TypeScript 技巧备忘录📝。

TypeScriptsTips

🕒 阅读时间:7分钟(约1224字)

可选类型不一定符合预期

const  = (?: { ?: string }) => {}

const  = (: { : string | undefined }) => {}

const  = (: { ?: string }) => {
  ()
  // 必须传入 traceId
  ({ : . })
}

模板字符串类型


type  = "en" | "pt"
type  = "header" | "footer"

type  = `${}_${}`

使用 Pick 和 Omit

interface Album {
  : string
  : string
  : string
  ?: number
  ?: { ?: string, ?: string }
}

// Pick 挑选
type  = < Album, 'title' | 'artist' >

// Omit 省略
type  = < Album, 'id' | 'releaseYear' | 'genre' >

// extract 提取
// ❌ 不起作用
type  = < Album, 'id' | 'artist' >

// exclude 排除
// 全量返回
type  = < Album, 'id' | 'artist' >

// ⚠️: 提取和排除只对联合类型起作用

使用 Extract 提取类型

type  = 'a' | 'b' | 1 | 2 | 8 | 'as'

// extract 提取
type  = <, number>

type  = <, string>

// Exclude 排除
type  = <, string>

type  = <, number>

使用 Exclude 排除类型

// exclude 排除

type  =
  | {
    : 'released'
    : string
  }
  | {
    : 'recording'
    : string
  }
  | {
    : 'mixing'
    : string
  }

// exclude 排除
type  = < , { : 'released' } >

更友好的显示类型

type  = {
  : string
  : number
} & {
  : boolean
} & {
  : string []
}

type  = {
  : string
  : number
} & <{ : boolean } & { : <'d', string[]> }, 'c'>
& { : 'en_US' | 'zh_CN' }

type  = 
type  = 

export type <> = {
  [ in keyof ]: []
} & {} // 添加 & {} 避免类型保持为引用形式

type  = <>

type  = { : true, : () => void }
type  = { ?: false, ?: never }

type  = { : boolean, : () => void } & ( | )

type  = <>

在字面量联合类型使用魔法 🧙‍♀️

type  =
  | 'gtp-4o'
  | 'o3-mini'
  | 'claude-sonnet-3.7'
  | 'gemini-1.5-flash'
  | (string & {})

const :  = 'gtp-4o'
const :  = 'qianwen'

// 平替方案
type < extends string> =  | <string, >
type  = <'red' | 'green' | 'blue'>

// ✅ 预设值
const :  = 'red'

// ✅ 自定义字符串(例如服务端配置返回的新值)
const :  = 'purple'

// ❌ 错误示例:number 不符合 string 类型
// const c: Color = 123

映射类型

type  = {
  : string
  : string
  : number
}

type  = {
  // [K in keyof User]: K
  // ========= ⬇️ =========
  // [K in keyof User]: [K]
  // ========= ⬇️ =========
  [ in keyof ]: []
}

type  = {
  readonly [ in keyof ]?: []
}

type  = {
  [ in keyof  as <>]: []
}

type  = {
  [ in keyof  as `get${<>}`]: []
}

type  = {
  [ in keyof  as `get${<>}`]: () => []
}

type < extends object> = {
  [ in <keyof , string> as `set${<>}`]?: (: []) => []
}
// ** 🔄 映射类型 ** -> 动态转换对象类型
type  = { : string; : string }

type <> = {
  [ in keyof ]: (: []) => void
}

type  = <>
  • Capitalize: 转换字符串类型第一个字母为大写。

索引映射类型 (IIMT)

type <> = { [ in keyof ]: [] } & {} // 添加 & {} 避免类型保持为引用形式

type  = {
  : { : string, : string }
  : { : string }
  : { : string, : unknown }
}

type  = {
  // [K in keyof Actions]: { type: K } & Actions[K]
  // ========= ⬇️ =========
  [ in keyof ]: <{ :  } & []>
}

// 🌰 索引映射类型的基本使用 (📝 从现有值推导类型)
type  = ['login']

// type Values_2 = Actions['login' | 'logout' | 'update']
// ========= ⬇️ =========
type  = [keyof ]

type  = [keyof ]

+ - 修饰符

+ - 修饰符可以添加或去掉 readonly?,如:

type  = { readonly ?: string, readonly ?: string }

// 去除所有属性上的 readonly 和可选修饰符
type <> = {
  -readonly [ in keyof ]-?: []
}

type  = <>

// 给所有属性添加 readonly 和可选修饰符
type <> = {
  +readonly [ in keyof ]+?: []
}

type  = <>

通过 as 重新(强制)映射类型

在TypeScript 4.1及更高版本中,可以在映射类型中使用as子句重新映射映射类型中的键,形式如下:

type <> = {
    [ in keyof  as ]: []
}

🌰 示例一,根据已知类型的键映射出新类型键:

type <> = {
    [ in keyof  as `get${<string & >}`]: () => []
}

interface Person {
    : string
    : number
    : string
}

type  = <Person>

🌰 示例二:映射任意联合类型:

type < extends { : string }> = {
    [ in  as ["kind"]]: (: ) => void
}

type  = { : "square", : number, : number }
type  = { : "circle", : number }

type  = < | >

// 使用示例
const :  = {
  : ({ , ,  }) => {},
  : ({ ,  }) => {}
}

Last updated on