11. 内置类型

63 阅读2分钟

Partial

Partial 给属性类型添加可选符号? image.png

interface Person{
    name: string
    age: number
}
let person: Partial<Person> = {} // 没有 ts 提示

// 原理
type MyPartial<T> = {
    [K in keyof T]?: T[K]
}
interface Person{
    name: string
    age: number
}
let person: MyPartial<Person> = {}

DeepPartial

上面的方式,如果对象是嵌套的,则嵌套对象里面的属性还是必填的

// 对象嵌套
interface Address{
    location: string
}
interface Person{
    name: string
    age: number
    address: Address
}
let p: Partial<Person> = {
    address:{} // ts 提示:类型 "{}" 中缺少属性 "location",但类型 "Address" 中需要该属性
}
// 如果写了 address ,就要把 address 的属性写全,Partial 没有给对象的深层属性变成可选属性,可以自己封装一个 DeepPartial
type DeepPartial<T> = {
    [K in keyof T]?:T[K] extends object ? DeepPartial<T[K]> : T[K]
}
let p: DeepPartial<Person> = {
    address:{} 
}

Required

require 会校验第一层是必填类型

interface people{
    name?: string
    age?:number
}
let p: Required<people> = {} // ts 提示:类型“{}”缺少类型“Required<people>”中的以下属性: name, age

// 原理
interface Person{
    name?: string
    age?: number
}
type MyRequired<T> = {
    [K in keyof T]-?:T[K]
}
type r1 = MyRequired<Person>
/*
    {
        name: string;
        age: number;
    }
*/
let p:MyRequired<Person> = {} // 类型“{}”缺少类型“MyRequired<Person>”中的以下属性: name, age

Readonly

将类型转换为 Readonly 只读属性

interface Person{
    name: string
    age: number
}
type ReadonlyPerson = Readonly<Person>
/*
type ReadonlyPerson = {
    readonly name: string;
    readonly age: number;
}
*/
interface Person{
    name: string
    age: number
}
type ReadonlyPerson = Readonly<Person>
let p: ReadonlyPerson = {
    name: 'lisi',
    age:18
}
p.name = "zhangsan" // 无法为“name”赋值,因为它是只读属性。

// 将仅读属性变成可修改属性
interface Person{
    name: string
    age: number
}
type ReadonlyPerson = Readonly<Person>
type cancelReadonly<T> = {
    -readonly [K in keyof T]: T[K]
}
type cancelPerson = cancelReadonly<ReadonlyPerson>
/*
type cancelPerson = {
    name: string;
    age: number;
}
*/

Pick

挑选某个属性

interface Person{
    name: string
    age: number
    sex:number
}
type pic = Pick<Person, 'name' | 'age'>
/**
type pic = {
    name: string;
    age: number;
}
*/

// 原理
interface Person{
    name: string
    age: number
    sex:number
}
type MyPick<T, K extends keyof T> = {
    [key in K]:T[key]
}

interface Person{
    name: string
    age: number
    sex:number
}
type MyPick<T, K extends keyof T> = {
    [key in K]:T[key]
}
let p: MyPick<Person,'name'> = {
    name:'zhangsan'
}

Omit

Omit 在所有属性中排除不需要的

interface Person{
    name: string
    age: number
    sex:number
}
let p: Omit<Person, 'name'> = {
    age: 18,
    sex: 1
}

// 原理
interface Person{
    name: string
    age: number
    sex:number
}
type MyOmit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
let person: MyOmit<Person, 'name'> = {
    age: 18,
    sex:1
}
// 属性类型合并
interface P1{
    name: string
    sex: number
}
interface P2{
    name: string
    sex: string
}
type fixType = P1 & P2
/*
{
    name: string
    sex:never
}
 */
let person: fixType = {
    name: 'lisi',
    sex:1 // 不能将类型“number”分配给类型“never”
}

// 但是我们希望P2的属性类型可以覆盖P1的属性类型,而不是 never 
function mixin<T, K>(a: T, b: K):Omit<T,keyof K> & K {
    return { ...a, ...b }
}
let p = mixin({
    name: 'zhangsan',
    age: 18,
    b:1
}, {
    name: 123,
    age: 19,
    c:1
})

type Computed<T> = {
    [K in keyof T]: T[K]
}
type nameType = Computed<typeof p>

/*
type nameType = {
    b: number;
    name: number;
    age: number;
    c: number;
}
 */

Record

let obj: Record<string,any> = { name:"jw", age:20 }