建议
🔍 搜索词
typeof typeof string literal value redeclare
在创建此问题之前,您搜索的关键词列表。请在这里写下它们,以便其他人更容易找到此建议并提供反馈。
✅ 可实现性检查清单
我的建议符合以下准则:
- 这不会对现有的TypeScript/JavaScript代码造成破坏性的更改
- 这不会改变现有JavaScript代码的运行时行为
- 这可以在不根据表达式的类型发出不同的JS的情况下实现
- 这不是一个运行时特性(例如库功能、具有JavaScript输出的非ECMAScript语法、JS的新语法糖等)
- 此功能将与 TypeScript's Design Goals 一致。
⭐ 建议
如果一个值已知为特定的原始类型或类型的联合,例如 string
或 number | string
,那么 typeof typeof
应该返回确切的字符串字面量类型,例如 "string"
或 "number" | "string"
,分别对应。
换句话说:如果 typeof <value>
将知道返回其中一个或多个字符串字面量,那么 TypeScript 应该给出比仅 string
更具体的类型。
📃 动机示例
当变量旨在存储 typeof
表达式的结果时,TypeScript应该能够推断出其字符串字面量类型,而不仅仅是它是一个 string
原始类型。
这段代码中不应有错误:
let myTypeOf: 'number' | 'string';
myTypeOf = typeof 'abc';
myTypeOf = typeof 123;
今天:
Type '"string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"' is not assignable to type '"string" | "number"'.
Type '"bigint"' is not assignable to type '"string" | "number"'.
💻 用例
请参阅此变量声明:https://github.com/typescript-eslint/typescript-eslint/pull/3891/files#diff-8a7d4566dbe9356145e8b86ccefa6d7a164c0b77818beb78d789e1089e9c4bc4R39
理想情况下,我们希望将其称为 let memberType: 'noInitializer' | 'number' | 'string' | undefined
,但稍后 typeof member.initializer.value
返回的是 string
而不是 'number' | 'string'
。
编辑:这也导致了 typescript-eslint/typescript-eslint#3453 ,所以这可能是一个bug?
4条答案
按热度按时间ldioqlga1#
在之前的讨论中提到了 #16314
u2nhd7ah2#
解:
列出所有可能的情况。
计算每种情况下的概率,并将结果相加。
得到最终答案。
svmlkihl3#
我理解原始类型 -
boolean
,number
,string
很容易缩小,但仍然存在防御性编程的问题 - 例如,如果x
缩小为'number'
,如何允许typeof x === 'undefined'
?从类型系统的Angular 来看,这并不是那么明确。在这种情况下,当然TS可以“允许”这种“不必要的”检查,因为
undefined
是一个唯一的类型,但'undefined'
根本不是。我认为不幸的是,由于遗留标准,仍有大量的代码库使用
typeof x === 'undefined'
检查而不是x === undefined
,所以这可能不是一件你可以“忽略”的事情。也许可以将
'undefined'
合并到typeof
中?但从API设计的Angular 来看,这确实有异味。我个人认为你的类型应该与现实相符 - 防御性编程与你定义的类型相反是有异味的 - 但我也理解并非每个代码库都可以或应该以这种方式工作。
是的,TS运行的结构化类型模型使得“对象”情况变得更加复杂,因为“对象”类型不一定是“对象”。
有人可能会认为最“正确”的做法是不缩小类型 - 但这可能会让大多数不熟悉TS类型系统的人大吃一惊。
如果你把它当作一个对象来处理,那么它是基于这样一个假设:(在TS的大规模范围内)很可能在某些代码库中并不成立 - 这意味着你在惊讶不同的人群。
所以我想这并不能真正通过“不会让任何人感到惊讶的功能”测试,因为有些事情如果你不了解TS的类型系统可能会让人感到惊讶?
wfveoks04#
我猜这并不能通过“不会让任何人感到惊讶的功能”测试,因为如果你不了解TS的类型系统,某些事情可能会让人感到惊讶?
我还会进一步说,即使你了解TS的类型系统,这里的结果仍然会看起来令人惊讶/不稳定,除非你真正以防御性的方式去思考,这是人们经常抱怨的不直观的行为。
我们甚至还没有提到
"function"
在几乎任何对象类型的结果中应该是什么,这将是一个进一步的混淆点。