ts utility-types ​​​​​​​ 源码解读 Special operators

原创
08/30 13:59
阅读数 32

特殊类型, 有的不太常用

 

ReturnType 函数返回值

通过infer拿到函数的返回值

type ReturnType<T extends (...args: any) => any> = T extends (
  ...args: any
) => infer R
  ? R
  : any;

function num2str(n: number): string {
  return "num" + n.toString();
}



type str = ReturnType<typeof num2str>;

InstanceType

type InstanceType<T extends new (...args: any) => any> = T extends new (
  ...args: any
) => infer R
  ? R
  : any;

class Dog {}

type DogType = InstanceType<typeof Dog>;

const d: DogType = new Dog();

PromiseType  promise的返回值

type PromiseType<T extends Promise<any>> = T extends Promise<infer U>
  ? U
  : never;

// function getData(): Promise<number>
function getData() {
  return new Promise<number>((resolve) => {
    setTimeout(() => {
      resolve(1);
    }, 1000);
  });
}

async function main() {
  type num = PromiseType<ReturnType<typeof getData>>;
  const res: num = await getData();
  console.log("res", res); // res 1
}

main();

 

Unionize 将对象的键值拆分, 分别作为类型, 最后返回一个联合类型

type Unionize<T extends object> = {
    [P in keyof T]: { [Q in P]: T[P] };
}[keyof T];
type Props = { name: string; age: number; visible: boolean };
/*
type UnionizedType = {
    name: string;
} | {
    age: number;
} | {
    visible: boolean;
}
*/
type UnionizedType = Unionize<Props>;

 

UnionToIntersection 

将联合类型转换为交叉类型

type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
  k: infer I
) => void
  ? I
  : never;

/*

type t = {
    name: string;
} & {
    age: number;
} & {
    visible: boolean;
}

*/
type t0 = { name: string } | { age: number } | { visible: boolean };
type t = UnionToIntersection<t0>;
const v0: t0 = {
  name: "a",
};
const v: t = {
  name: "a",
  age: 1,
  visible: true,
};

Brand 标签

为一个类型加上一个标签, 用于表示类别, 返回的新类型基于传入的类型, 但是拓展了一个标示属性

export type Brand<T, U> = T & { __brand: U };
type USD = Brand<number, "USD">;
type EUR = Brand<number, "EUR">;

const tax = 5 as USD;
const usd = 10 as USD;
const eur = 10 as EUR;

function gross(net: USD): USD {
  return (net + tax) as USD;
}

// Expect: No compile error
gross(usd);
// Expect: Compile error (Type '"EUR"' is not assignable to type '"USD"'.)
gross(eur);

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部