# TypeScript工具类型

## TypeScript实用工具

## 全局工具

TypeScript提供了一些实用工具类型，这些工具类型全局可用。

## 异步

### Awaited

`Awaited`用于获取`Promise<Type>`中的`Type`类型，这和async函数中的`await`很相似，只不过async函数中的`await`是取得Promise的值，而`Awaited`则是取得值的类型。

Type不仅可以是一个Promise类型，也可以是一个嵌套的Promise类型、字符串等基本类型，甚至还可以是一个联合类型。

```tsx
type A = Awaited<Promise<string>>;
// A = string;
type A = Awaited<Promise<Promise<number>>>;
// A = string;
type A = Awaited<string>
// A = string;
type A = Awaited<boolean | Promise<number>>;
// A = boolean | number
```

示例

```tsx
type GetListType = ()=>Promise<string>
const getList:GetListType = ()=> new Promise((resolve)=>{
    setTimeout(()=>{
        resolve('123')
    }, 1000)
})

async function fn(){
    // ReturnType接收函数，并返回该函数返回值的类型
    // 在这个例子里ReturnType<GetListType> = Promise<string>
    const res:Awaited<ReturnType<GetListType>> = await getList()
}
```

## 对象属性转换

### Partial

`Partial`的作用是将`Type`中所有的属性都转换成可选的。

例如有些时候我们需要将接口中的所有属性都转换成可选的，这个时候没必要再重新写一遍，只需要用`Partial`类型转换一下即可。

```tsx
interface Person {
    name: string;
    age: number
}

type ChangePersonType = Partial<Person>

function changePerson(arg: ChangePersonType){

}
changePerson({name: '李四'}) // ✔
changePerson({name: '李四',age: 18}) // ✔
```

### Required

`Required`类型的作用刚好与`Partial`相反，它会将Type`内的`所有属性都转换成必填的。

```tsx
type CreatePersonType = Required<ChangePersonType>

function createPerson(arg: CreatePersonType){

}
createPerson({name: '李四',age: 18}) // ✔
createPerson({name: '李四'})     // ✖
```

### Readonly

顾名思义`Readonly`的作用是将`Type`中的所有属性都转换成只读的。

```tsx
interface Person {
    name: string;
    age: number
}

const xiaoMing: Readonly<Person> = {name: '小明', age: 20}
xiaoMing.age += 1; // ✖
```

## 根据条件构造对象类型

### Record\<Keys,Type>

Record会构建一个包含所有键为`Key`，类型为`Type`的属性的对象类型，例如：

```tsx
type PersonType = Record<'name' | 'age', string>

/*
类似于
interface PersonType  {
	name: string;
  age: string;
}
*/
const pserson:PersonType = {name: '小明', age: '21'}
```

Type也可以是对象类型：

```tsx
interface CatInfo {
  age: number;
  breed: string;
}
 
type CatName = "miffy" | "boris" | "mordred";
 
const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
  mordred: { age: 16, breed: "British Shorthair" },
};
```

### Pick\<Type, Keys>

`Pick`的作用是从`Type`中取得所有`Keys`属性来构建一个新的对象类型。

```tsx
interface Boy {
    name: string;
    age: number;
    gender: "男"
}

type Person = Pick<Boy, 'name' | 'age'>
const xiaoMing:Person = {
    name: "小明",
    age: 18,
}
```

### Omit\<Type, Keys>

`Omit`和`Pick`类似，不过`Omit`是所有移除`Key`属性，并用剩余的属性来构建一个新的对象类型。

`Pick`的那个例子可以用`Omit`重写，效果相同。

```tsx
interface Boy {
    name: string;
    age: number;
    gender: "男"
}
type Person = Omit<Boy, 'gender'>
const xiaoMing:Person = {
    name: "小明",
    age: 18,
}
```

## 联合类型

### Exclude\<UnionType, ExcludedMenbers>

`Exclude`会返回一个将`UnionType`联合类型中所有的`ExcludedMenbers`成员都移除的联合类型，例如：

```tsx
type IsBoy = 1 | -1 | 0; // 是 | 否 | 不确定
const isBoy: Exclude<IsBoy, 0> = 0;  // ✖
const isBoy: Exclude<IsBoy, 0> = 1;  // ✔
// IsBoy = 1 | -1
```

### **Extract\<Type, Union>**

Extract会返回`Type`和`Union`的交集。

```tsx
type IsBoy = 1 | -1 | 0
const isBoy: Extract<IsBoy, 1 | -1> = 1;
// IsBoy = 1 | -1
```

### NonNullable

NonNullabe会将Type中的null和undefined类型移除，并返回一个新的类型。

```tsx
type A = 1 | 0 | null | undefined;
const a: NonNullable<A> = null // ✖
const b: NonNullable<A> = undefined // ✖
const c: NonNullable<A> = 1 // ✔
```

## 函数

### Parameters

返回包含函数所有参数的元组或者数组。

```tsx
type Fn1 = (...args: number[])=>string
type Fn2 = (age: number, name: string) => string

type A = Parameters<Fn1>; // number[]
const a: A = [1]

type B = Parameters<Fn2>  // []
const b:B = [18,'小明'] 
```

### ReturnType

返回函数返回值的类型。

```tsx
type Fn1 = (...args: number[])=>string

type A = ReturnType<Fn1>; // string
const a: A = '1'
```

### ConstructorParameters

从构造函数类型的参数类型构造元组或数组类型。它产生一个包含所有参数类型的元组类型（如果 Type 不是函数，则类型 never ）。

```tsx
type T0 = ConstructorParameters<ErrorConstructor>;
// type T0 = [message?: string | undefined]

class Fn{
    constructor(a:string, b?:number){}
}
type T1 = ConstructorParameters<typeof Fn>;
// type T1 = [a: string, b?: number | undefined]
```

### InstanceType

构造一个由 Type 中构造函数的实例类型组成的类型。

```tsx
class Fn{
    a: string;
    b?:number;
    constructor(a:string, b?:number){
        this.a = a;
        this.b = b
    }
}
type T1 = InstanceType<typeof Fn>;
const t1: T1 = new Fn('',1)  // ✔
const t2:T1 = new Error('')  // ✖
```

### ThisParameterType

提取函数类型的 `this`参数的类型，如果函数类型没有 `this`参数，则为`unknown`

```tsx
function toHex(this: Number, name: string) {
  return this.toString() + name;
}
console.log(toHex.call(10, ' name'))
// 10 name

type ToHexThisParameters = ThisParameterType<typeof toHex>
// type ToHexParameters = Number
const toHexThisParameters:ToHexThisParameters = Number(10)
```

### OmitThisParameter

从 `Type`中移除 `this`参数。

如果 `Type`没有显式声明this，则直接返回 `Type`。否则，将从Type中创建一个不包含`this`的新函数类型。

```tsx
function toHex(this: Number, name: string) {
  return this.toString() + name;
}

type ToHexThisParameters = OmitThisParameter<typeof toHex>
// type ToHexThisParameters = (name: string) => string
const toHexThisParameters:ToHexThisParameters = (name: string)=>name;
```

如果函数没有显示声明this类型：

```tsx
function toHex(name: string) {
  return name;
}

type ToHexThisParameters = OmitThisParameter<typeof toHex>
// type ToHexThisParameters = (name: string) => string
const toHexThisParameters:ToHexThisParameters = (name: string)=>name;
```

## 字符串

`Uppercase<StringType>` : 将字符串中的每个字符转换为大写。

`Lowercase<StringType>` : 将字符串中的每个字符转换为小写。

`Capitalize<StringType>` : 将字符串中的第一个字符转换为等效的大写字母。

`Uncapitalize<StringType>` : 将字符串中的第一个字符转换为等效的小写字母。

```tsx
const lowercase: Lowercase<string> = 'a'
const uppercase: Uppercase<string> = "A"
const capitalize: Capitalize<string> = 'Aa'
const uncapitalize:Uncapitalize<string> = 'aA'

const a: Lowercase<'A'> = 'a'
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://1425816423.gitbook.io/my-knowledge-base/qian-duan-ji-shu/typescript/typescript-gong-ju-lei-xing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
