Wan*_*ang 3 typescript typescript-typings mapped-types
这是代码
class A {
x = 0;
y = 0;
visible = false;
render() {
return 1;
}
}
type RemoveProperties<T> = {
readonly [P in keyof T]: T[P] extends Function ? T[P] : never//;
};
type JustMethodKeys<T> = ({ [P in keyof T]: T[P] extends Function ? P : never })[keyof T];
type JustMethods<T> = Pick<T, JustMethodKeys<T>>;
type IsValidArg<T> = T extends object ? keyof T extends never ? false : true : true;
type Promisified<T extends Function> =
T extends (...args: any[]) => Promise<any> ? T : (
T extends (a: infer A, b: infer B, c: infer C, d: infer D, e: infer E, f: infer F, g: infer G, h: infer H, i: infer I, j: infer J) => infer R ? (
IsValidArg<J> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) => Promise<R> :
IsValidArg<I> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) => Promise<R> :
IsValidArg<H> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) => Promise<R> :
IsValidArg<G> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => Promise<R> :
IsValidArg<F> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F) => Promise<R> :
IsValidArg<E> extends true ? (a: A, b: B, c: C, d: D, e: E) => Promise<R> :
IsValidArg<D> extends true ? (a: A, b: B, c: C, d: D) => Promise<R> :
IsValidArg<C> extends true ? (a: A, b: B, c: C) => Promise<R> :
IsValidArg<B> extends true ? (a: A, b: B) => Promise<R> :
IsValidArg<A> extends true ? (a: A) => Promise<R> :
() => Promise<R>
) : never
);
var a = new A() as JustMethods<A> // I want to JustMethod && Promisified
a.visible // error
var b = a.render() // b should be Promise<number>
Run Code Online (Sandbox Code Playgroud)
如何执行呢?我想删除可见和Promisify渲染方法,如何将Promisified和JustMethods合成?
如何执行呢?我想删除可见和Promisify渲染方法,如何将Promisified和JustMethods合成?
您需要使用仅在每个属性上使用JustMethodKeys和使用类型的方法的映射类型Promisified
class A {
x = 0;
y = 0;
visible = false;
render() {
return 1;
}
}
type JustMethodKeys<T> = ({ [P in keyof T]: T[P] extends Function ? P : never })[keyof T];
type IsValidArg<T> = T extends object ? keyof T extends never ? false : true : true;
type Promisified<T extends Function> =
T extends (...args: any[]) => Promise<any> ? T : (
T extends (a: infer A, b: infer B, c: infer C, d: infer D, e: infer E, f: infer F, g: infer G, h: infer H, i: infer I, j: infer J) => infer R ? (
IsValidArg<J> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) => Promise<R> :
IsValidArg<I> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) => Promise<R> :
IsValidArg<H> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) => Promise<R> :
IsValidArg<G> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => Promise<R> :
IsValidArg<F> extends true ? (a: A, b: B, c: C, d: D, e: E, f: F) => Promise<R> :
IsValidArg<E> extends true ? (a: A, b: B, c: C, d: D, e: E) => Promise<R> :
IsValidArg<D> extends true ? (a: A, b: B, c: C, d: D) => Promise<R> :
IsValidArg<C> extends true ? (a: A, b: B, c: C) => Promise<R> :
IsValidArg<B> extends true ? (a: A, b: B) => Promise<R> :
IsValidArg<A> extends true ? (a: A) => Promise<R> :
() => Promise<R>
) : never
);
type PromisifyMethods<T> = {
// We take just the method key and Promisify them,
// We have to use T[P] & Function because the compiler will not realize T[P] will always be a function
[P in JustMethodKeys<T>] : Promisified<T[P] & Function>
}
//Usage
declare var a : PromisifyMethods<A>
a.visible // error
var b = a.render() // b is Promise<number>
Run Code Online (Sandbox Code Playgroud)
编辑
自从原始问题得到回答以来,打字稿已改善了该问题的可能解决方案。通过在剩余参数和扩展表达式中添加元组,我们现在不需要具有所有的重载Promisified:
type JustMethodKeys<T> = ({ [P in keyof T]: T[P] extends Function ? P : never })[keyof T];
type ArgumentTypes<T> = T extends (... args: infer U ) => any ? U: never;
type Promisified<T> = T extends (...args: any[])=> infer R ? (...a: ArgumentTypes<T>) => Promise<R> : never;
type PromisifyMethods<T> = {
// We take just the method key and Promisify them,
// We have to use T[P] & Function because the compiler will not realize T[P] will always be a function
[P in JustMethodKeys<T>] : Promisified<T[P]>
}
//Usage
declare var a : PromisifyMethods<A>
a.visible // error
var b = a.render("") // b is Promise<number> , render is render: (k: string) => Promise<number>
Run Code Online (Sandbox Code Playgroud)
这不仅更短,而且解决了许多问题
| 归档时间: |
|
| 查看次数: |
486 次 |
| 最近记录: |