Open Mike-Zhu opened 4 years ago
TypeScript 题
/* eslint-disable import/prefer-default-export */ /* eslint-disable class-methods-use-this */ import { expect } from 'chai'; interface Action<T> { payload?: T; type: string; } type FuncName<T> = { [P in keyof T]: T[P] extends Function ? P : never; }[keyof T]; class EffectModule { count = 1; message = 'hello!'; delay(input: Promise<number>) { return input.then((i) => ({ payload: `hello ${i}!`, type: 'delay', })); } setMessage(action: Action<Date>) { return { payload: action.payload!.getMilliseconds(), type: 'set-message', }; } } type ParamType<T extends (input: any) => any> = T extends (input: infer P) => any ? P : T; type UnPromise<T> = T extends Promise<infer P> ? P : T; type UnWrap<T> = T extends Action<infer U> ? U : Unpromise<T>; // 修改 Connect 的类型,让 connected 的类型变成预期的类型 type Connect = (module: EffectModule) => { [T in FuncName<EffectModule>]: (param: UnWrap<ParamType<EffectModule[T]>>) => UnPromise<ReturnType<EffectModule[T]>> }; const connect: Connect = (m) => ({ delay: (input: number) => ({ type: 'delay', payload: 'hello 2', }), setMessage: (input: Date) => ({ type: 'set-message', payload: input.getMilliseconds(), }), }); type Connected = { delay(input: number): Action<string>; setMessage(action: Date): Action<number>; }; export const connected: Connected = connect(new EffectModule());
TypeScript 题