TypeScript -类型强制转换没有返回预期的假值



如果类型不匹配,我希望在运行时对字符串进行强制转换以返回一个假值。也就是说,当我对ts-node@10.7.0运行以下命令时,我遇到了意想不到的结果:

$ ts-node
> 0 as 'B' | 'C' | 'D' || 'foo'         // ✅ throws precompiler error as expected
--------------
> '' as 'B' | 'C' | 'D' || 'foo'        // ✅ prints 'foo' as expected
'foo' 
> undefined as 'B' | 'C' | 'D' || 'foo' // ✅ prints 'foo' as expected
'foo' 
> null as 'B' | 'C' | 'D' || 'foo'      // ✅ prints 'foo' as expected
'foo' 
> 'B' as 'B' | 'C' | 'D' || 'foo'       // ✅ prints 'B' as expected
'B' 
> 'A' as 'B' | 'C' | 'D' || 'foo'       // ❌ prints 'A' instead of 'foo' <-- UNEXPECTED
'A'

我显然误解了casting是如何工作的,但是我如何实现我试图实现的逻辑,我期望'A' as 'B' | 'C' | 'D'返回一个假值?

as是一个类型断言,它没有运行时效果。相反,您需要对该值进行一些手动检查。比如:

const allowed = new Set(['B', 'C', 'D']);
const input: string = 'A';
const value = allowed.has(input) ? input : 'foo';

然后可以使用as断言该值为'B' | 'C' | 'D' | 'foo'

Playground (runnable)
Playground使用type-fu不重复字面值

最干净的"在我看来,处理未知字面量的方法是使用类型保护。

type YourLiteralType = 'B' | 'C' | 'D'
// Important part is the return type, and returning a boolean value
function isYourLiteralType(input: unknown): input is YourLiteralType {
return input === 'B' || input === 'C' || input === 'D'
}
const a = 'A'
// Works with ifs
if (isYourLiteralType(a)) {
// a is "casted" to YourLiteralType
}

function doSomethingWithYourLiteralType(input: YourLiteralType) {
// Raises a compiler error if not called with the appropriate type
}
// Also works with ternaries
const x = isYourLiteralType(a) ? doSomethingWithYourLiteralType(a) : undefined

最新更新