gpt4 book ai didi

typescript - 当看似相同的三元运算符构造没有时,为什么使用 'if-else' 语句会产生 TypeScript 编译器错误?

转载 作者:行者123 更新时间:2023-12-03 17:20:14 25 4
gpt4 key购买 nike

我有一个函数旨在返回值 IDBValidKey或转换为 IDBValidKey 的内容.如果我使用三元运算符编写函数,它可以正常工作,但如果我将其编写为 if-else 语句,则会导致编译器错误:

interface IDBValidKeyConvertible<TConverted extends IDBValidKey> {
convertToIDBValidKey: () => TConverted;
}

function isIDBValidKeyConvertible<TConvertedDBValidKey extends IDBValidKey>(object: unknown): object is IDBValidKeyConvertible<TConvertedDBValidKey> {
return typeof((object as IDBValidKeyConvertible<TConvertedDBValidKey>).convertToIDBValidKey) === "function";
}

type IDBValidKeyOrConverted<TKey> = TKey extends IDBValidKeyConvertible<infer TConvertedKey> ? TConvertedKey : TKey;

function getKeyOrConvertedKey<TKey extends IDBValidKey | IDBValidKeyConvertible<any>>(input: TKey): IDBValidKeyOrConverted<TKey> {
if (isIDBValidKeyConvertible<IDBValidKeyOrConverted<TKey>>(input)) {
return input.convertToIDBValidKey();
} else {
return input;
}
}

function getKeyOrConvertedKeyTernary<TKey extends IDBValidKey | IDBValidKeyConvertible<any>>(input: TKey): IDBValidKeyOrConverted<TKey> {
return (isIDBValidKeyConvertible<IDBValidKeyOrConverted<TKey>>(input)) ? input.convertToIDBValidKey() : input;
}
getKeyOrConvertedKeyTernary不产生错误,但 else getKeyOrConvertedKey块产生这个错误:
Type 'TKey' is not assignable to type 'IDBValidKeyOrConverted<TKey>'.
Type 'string | number | Date | ArrayBufferView | ArrayBuffer | IDBArrayKey | IDBValidKeyConvertible<any>' is not assignable to type 'IDBValidKeyOrConverted<TKey>'.
Type 'string' is not assignable to type 'IDBValidKeyOrConverted<TKey>'.

三元运算符和 if-else 语句不是等价的吗?

谢谢!

最佳答案

Why does using an 'if-else' statement produce a TypeScript compiler error when a seemingly identical ternary operator construct does not?



简答

TypeScript 看到一个 if-else作为具有多个表达式的语句,每个表达式都有独立的类型。 TypeScript 将三元视为一个表达式,其联合类型为真和假。有时,联合类型变得足够宽,编译器不会提示。

详细解答

Aren't the ternary operator and the if-else statement equivalent?



不完全的。

差异源于三元是一个表达式。有一个 conversation here Ryan Cavanaugh 解释了三元语句和 if/else 语句之间的区别。值得一提的是,三元表达式的类型是其 true 的并集。和 false结果。

对于您的特定情况,三元表达式的类型是 any .这就是编译器不提示的原因。你的三元是 input 的并集类型和 input.convert()返回类型。在编译时, input类型扩展 Container<any> ;因此 input.convert()返回类型是 any .自从与 any 结盟以来是 any ,你的三元类型是,嗯, any .

为您提供快速解决方案 是要改 anyunknown<TKey extends IDBValidKey | IDBValidKeyConvertible<any> .这将使 if-else 和三元产生编译器错误。

简化示例

这是 a playground link并简化了您的问题。尝试更改 anyunknown查看编译器如何响应。
interface Container<TValue> {
value: TValue;
}

declare function hasValue<TResult>(
object: unknown
): object is Container<TResult>;

// Change any to unknown.
const funcIfElse = <T extends Container<any>>(input: T): string => {
if (hasValue<string>(input)) {
return input.value;
}

return input;
};

// Change any to unknown.
const funcTernary = <T extends Container<any>>(input: T): string =>
hasValue<string>(input)
? input.value
: input;

关于typescript - 当看似相同的三元运算符构造没有时,为什么使用 'if-else' 语句会产生 TypeScript 编译器错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61685303/

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