Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript tricks #19

Open
vivipure opened this issue Jul 12, 2022 · 4 comments
Open

TypeScript tricks #19

vivipure opened this issue Jul 12, 2022 · 4 comments

Comments

@vivipure
Copy link
Owner

vivipure commented Jul 12, 2022

Utility Types

Omit

Omit 可以忽略对象类型中的某些属性

type User = {
  name: string
  age: number
  id: string
}

type SimpleUser = Omit<User, "name" >

等同于

type SimpleUser = {
     age: number;
     id: string;
}

自身实现,利用Exclude 剔除属性

type OwnOmit<T , P extends keyof T> = {
  [K in Exclude<keyof T, P>]: T[K]
}

Pick

Pick 的功能和 Omit 相反,Pick 筛选出 对象类型中需要的属性

type SimpleUser = Pick<User, "name" >

等同于

type SimpleUser = {
     name: string;
}

本身的实现也很简单

type OwnPick<T , P extends keyof T> = {
  [K in P]: T[K]
}

Exclude

Omit的实现有用到 Exclude, 它的作用就是将第一个类型中,符合第二个类型中条件的类型剔除

对于 对象类型等,第二个类型是第一个类型的子集也可以达到效果

type TextExclude = Exclude<'number' | 'age', 'age'> // 'number'

自身实现

type MyExclude<T, U> = T extends U ? never : T

Extract

Extract的功能和 Exclude 相反, 它的作用就是将第一个类型中,符合第二个类型筛选的类型保留

type TextExclude = Exclude<'number' | 'age', 'age'> //  'age'

自身实现

type MyExclude<T, U> = T extends U ? T:  never

Partial

Partial可以让对象类型的每个属性变为可选

type UserPartial = Partial<User>

等同于

type UserPartial = {
    name?: string | undefined;
    age?: number | undefined;
    id?: string | undefined;
}

自身实现

type OwnPartial<T> = {
  [K in keyof T]?: T[K]
}

Required

Required可以让对象类型的的每个属性都变为必须

type UserRequired = Required<UserPartial>

等同于

type UserRequired = {
    name: string;
    age: number;
    id: string;
}

Required 的实现 使用了 -? ,语法奇怪但是很好理解

type OwnRequired<T> = {
  [K in keyof T]-?: T[K]
}

Record

Record 可以定义对象类型 键和值的类型

type A = Record<string, {name: string}>

自身实现

type OwnRecord<Key extends number | string | symbol , Value> = {
  [key in Key]: Value
}

ReturnType

ReturnType 可以返回函数类型的返回值类型

function test(username: string, password: string) {
  return { username, password }
}

type TestReturnType = ReturnType<typeof test>

等同于

type TestReturnType = {
    username: string;
    password: string;
}

自身实现

type OwnReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R: unknown

Parameters

Parameters 可以返回 函数类型的参数类型

function test(username: string, password: string) {
  return { username, password }
}

type TestParameterType = Parameters<typeof test>

等同于

type TestParameterType = [username: string, password: string, age: number]

它的实现也是通过 infer 来进行实现

type OwnParameters<T extends (...args: any[]) => any> = T extends (...args: infer P) => any ? P : unknown

Awaited

对于 async 函数或者返回一个 promise值时, 我们可以通过 Awaited 得到未被Promise包裹的类型

async function testUser() {
  return 2
}  


type TestUserResult1 = ReturnType<typeof testUser> // Promise<number>

type TestUserResult = Awaited<ReturnType<typeof testUser>> // number
@vivipure
Copy link
Owner Author

vivipure commented Jul 14, 2022

interface 与 type 区别

  1. interface 只能表示对象[函数也是对象哦],type 都可以
  2. interface 可以声明合并
  3. type 使用 & 合并
  4. 由于声明语句不同, interface 可以直接export default 声明一起用,type 只能先声明再导出

@vivipure
Copy link
Owner Author

vivipure commented Aug 3, 2022

tsconfig.json

npx tsc --init

生成 tsconfig.json

@vivipure
Copy link
Owner Author

遇到问题汇总

1. Element 类型不存在 style属性

使用 HTMLElement 即可。

@vivipure
Copy link
Owner Author

||= ,&&=,??=

看开源项目时,看到 ||= 的写法,其实从语法上就能大概知道意思。这个语法能够简写很多东西

let b = {}

if(!b.a} {
    b.a = []
}
b.a.push(1)

例如我们对 对象某个属性添加元素时,要先判断是否是数组。利用 ||=代码就简洁的多

b.a ||= []
b.a.push(1)

除了 ||=,还有&&=,??=.

let b: Record<string, undefined | any[] | number> = {
}


b.a ||= [] // b.a || b.a = []

b.c &&= [] // b.c && b.c = []

b.d ??= [] // b.d !== null && b.d !== undefined ? b.d : []

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant