打字稿 - 类型铸件未返回假冒值,如预期

发布于 2025-01-27 03:10:01 字数 789 浏览 4 评论 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'

我清楚地误解了铸造的工作原理,但是我如何实现我试图实现我期望'a''as'b'|的逻辑。 'C'| 'd'返回虚假值?

I would like the casting of a string at runtime to return a falsey value if the type is mismatched. Namely, when I run the following with [email protected], I encounter unexpected results:

$ 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'

I clearly misunderstand how casting works, but how do I implement the logic I am trying to achieve where I expected 'A' as 'B' | 'C' | 'D' to return a falsey value?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寒冷纷飞旳雪 2025-02-03 03:10:01

是是一种类型断言,它没有运行时效应。您需要对值进行一些手动检查。类似:

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

然后您可以断言值是'b'| 'C'| 'D'| 'foo'使用

Playground (runnable)
Playground using type-fu to not repeat literals

as is a type assertion, it does not have a runtime effect. You need to do some manual checking of the value instead. Something like:

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

You then can assert that value is 'B' | 'C' | 'D' | 'foo' using as.

Playground (runnable)
Playground using type-fu to not repeat literals

猫性小仙女 2025-02-03 03:10:01

我认为,与未知文字合作的“最清洁”方法是使用类型的后卫。

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

The "cleanest" way to work with unknown literals in my opinion is using a type guard.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文