gpt4 book ai didi

typescript - 条件类型 ReturnType 函数签名重载解析

转载 作者:搜寻专家 更新时间:2023-10-30 21:28:12 27 4
gpt4 key购买 nike

我正在尝试使用 typescript 2.8 的新 conditional types ,(尚未发布版本 2.8.0-dev.20180307),我不知道这是错误还是误用。我的重点是我的声明 MockedImplementation<F>可以是全功能匹配F , F 的返回类型, 如果返回类型为 FPromise ,那么它也可能是 promise 解决的问题——所有这些都将被 mockIt() 相应地包装起来。 .

type MockedImplementation<F> = 
F | // The function signature
((ReturnType<F extends (...args: any[]) => any ? F : any>) extends infer T
? T extends Promise<infer R>
? (T | R) // Or the promise or just the type that the promise resolves to
: T // or whatever type this is
: never);

interface Wrapped<T> {
result: T
}

function mockIt<F>(pretend : MockedImplementation<F>) : F {
throw new Error('Not Implemented'); // doesn't matter
}

interface SomeOperationA {
(parameters : { 'a': number[], 'b'?: string }) : Promise<string>;
}

mockIt<SomeOperationA>(() => Promise.resolve('hello')); // 👍 OK
mockIt<SomeOperationA>(Promise.resolve('hello')); // 👍 OK
mockIt<SomeOperationA>('hello'); // 👍 OK
mockIt<SomeOperationA>(42); // 👍 Type error.

mockItSomeOperationA有效,也许直接是因为没有函数签名覆盖。但是mockItSomeOperationB失败:

interface SomeOperationB {
(parameters : { 'a': number[], 'b'?: string }) : Promise<string>;
(parameters : { 'a': number[], 'b'?: string }, rawResponse : true) : Promise<Wrapped<string>>;
(parameters : { 'a': number[], 'b'?: string }, rawResponse : false) : Promise<string>;
}

mockIt<SomeOperationB>(() => Promise.resolve('hello')); // ❌ Type 'string' is not assignable to type 'Wrapped<string>'.
mockIt<SomeOperationB>(Promise.resolve('hello')); // 👍 OK
mockIt<SomeOperationB>('hello'); // 👍 OK
mockIt<SomeOperationB>(42); // 👍 Type error.

它似乎是交叉类型而不是联合它们?但我敢肯定它比这更细微。

我在某处看到一条关于“考虑最后一个重载,因为它可能是最普遍的重载”的注释,但我认为它在这里不相关,因为它的行为似乎并不重要。

编辑

@jcalz 是对的,有道理:

interface SomeOperationB {
(wrapped : true) : Promise<Wrapped<string>>;
(wrapped : false) : Promise<string>;
}

interface Wrapped<T> { result: T }

declare function acceptSomeOperationB(x: SomeOperationB): void;

acceptSomeOperationB(() => Promise.resolve('hello')); // ❌ Type 'string' is not assignable to type 'Wrapped<string>'.
acceptSomeOperationB(() => Promise.resolve({ result: 'hello' })); // ❌ Type '{ result: string; }' is not assignable to type 'string'.

最佳答案

没有条件类型的问题的较小再现:

declare function acceptSomeOperationB(x: SomeOperationB): void;
acceptSomeOperationB(() => Promise.resolve('hello')); // ❌ Type 'string' is not assignable to type 'Wrapped<string>'.

很明显,TypeScript 不认为箭头函数与 SomeOperationB 兼容。因为它不满足其中一个重载的签名。事实上,如果你通过 true作为该函数的第二个参数,它不会返回 Promise<Wrapped<string>> ,根据 SomeOperationB 的第二个签名要求.

一旦您决定如何解决该问题,它就应该开始工作(或者您至少可以继续处理条件类型的问题。)

祝你好运。

关于typescript - 条件类型 ReturnType 函数签名重载解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49158195/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com