# Partial 和 Required

//工具类型
interface IObj {
    a:string,
    b?:boolean,
    c?:number
}

//Partial<泛型>
//<> 里面对象全部类型 , 自动变成 可缺省类型 
let obj:Partial<IObj> = {
    a:"11",
    b:true,
    c:11
}

// Required<>
// <> 里面对象全部类型 , 自动变成不可缺省类型   ?失效
let obj2:Required<IObj> = {
    a:'11',
    b:true,
    c:10
}

# extends

extends关键字判断泛型参数P是否是string或者是number其中的一种,最终类型的确定由三元运算的结果决定。

type TypeFn<P> = P extends string | number ? P[] : P;
let m: TypeFn<number> = [1, 2, 3];
let m1: TypeFn<string> = ['1', '2', '3'];
let m2: TypeFn<boolean> = true;

# 类型推断 infer

类型推断infer相当于声明一个变量接收传入的类型

type ObjType<T> = T extends { name: infer N; age: infer A } ? [N, A] : [T];
let p: ObjType<{ name: string; age: number }> = ["张三", 1];
let p1: ObjType<{name: string}> = [{name: '张三'}];

# keyof

Keyof提取对象属性名、索引名、索引签名的类型;

interface NumAndStr {
  name: string;
  age: number;
  [key: number]: string | number;
}
type TypeKey = keyof NumAndStr; // number | 'name' | 'age'
let t:TypeKey = 'name';

# in

in是映射类型

type NumAndStr = number | string;
type TargetType = {
  [key in NumAndStr]: string | number;
};

let obj: TargetType = {
    1: '123',
    "name": 123
}

注意:

  1. 我们只能在类型别名定义中使用 in,如果在接口(interface)中使用,则会提示一个错误
  2. in 和 keyof 也只能在类型别名定义中组合使用

# typeof

typeof 的主要用途是在类型上下文中获取变量或者属性的类型

// 推断变量的类型
let strA = "2";
type KeyOfType = typeof strA; // string

// 反推出对象的类型作为新的类型
let person = {
    name: '张三',
    getName(name: string):void {
        console.log(name);
    }
}
type Person = typeof person;