Typescript 函数应返回承诺<;字符串>;,显然回报承诺<;未知>;但仍在编译
下面是我遇到的一些奇怪的代码。我已经修复了它,但我不明白它为什么会编译:Typescript 函数应返回承诺<;字符串>;,显然回报承诺<;未知>;但仍在编译,typescript,Typescript,下面是我遇到的一些奇怪的代码。我已经修复了它,但我不明白它为什么会编译: const stringOrNull:()=>Promise=()=> Promise.resolve(Math.random()Promise=()=> 新承诺(解决=> stringOrNull()。然后(结果=>解析(结果?结果:未定义)) ); //最终将与 //(节点:20784)未经处理的PromisejectionWarning:TypeError:无法读取未定义的 […数组(10).keys()].forE
const stringOrNull:()=>Promise=()=>
Promise.resolve(Math.random()<0.5?“你好,世界。”:null);
//为什么要编译?
const stringornullwird:()=>Promise=()=>
新承诺(解决=>
stringOrNull()。然后(结果=>解析(结果?结果:未定义))
);
//最终将与
//(节点:20784)未经处理的PromisejectionWarning:TypeError:无法读取未定义的
[…数组(10).keys()].forEach(异步()=>
console.log((wait stringornullwird()).toLocaleLowerCase())
);
我重写了这个函数,只需将返回的Promise
放在一个临时变量中,这样我就可以检查TypeScript推断出的类型:它似乎是unknown
,然后函数就不会编译了
//未按预期编译
//类型“()=>Promise”不可分配给类型“()=>Promise”。
//类型“Promise”不可分配给类型“Promise”。
//类型“未知”不可分配给类型“字符串”。ts(2322)
const stringOrNullUnknown:()=>Promise=()=>{
//警察:答应我
const p=新承诺(解析=>
stringOrNull()。然后(结果=>解析(结果?结果:未定义))
);
返回p;
};
因此,我不明白第二种形式与上面的形式有何不同,以及为什么上面的形式会编译,破坏类型安全?事实上,原因不是
Promise
可分配给Promise
。当您将新承诺
分配给预期的承诺时,TS将发现新承诺(…)
实际上是新承诺(…)
。在第二个示例中,当您将其放入变量中时,TS将无法确定类型参数是什么,并使用unknown
真正的原因是这是允许的,因为这是Promise
构造函数的签名:
new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
上述情况更简单,可能是一个错误。
或者,如果异步逻辑变得太复杂,请使用async
/wait
:
const stringOrNullWeird: () => Promise<string> = async () => {
const result = await stringOrNull()
return result ? result : undefined;
}
const stringornullwird:()=>Promise=async()=>{
const result=await stringOrNull()
返回结果?结果:未定义;
}
两者都是错误。调用Promise
构造函数通常是多余的
const stringOrNullWeird: () => Promise<string> = async () => {
const result = await stringOrNull()
return result ? result : undefined;
}