【发布时间】:2021-05-10 13:10:28
【问题描述】:
有没有办法将字符串类型文字(不是运行时值)转换为其对应的数字类型文字,例如'1' 到 1?
我想将变量缩小为对象的键(注意程序员断言obj 的类型是准确的,如TS doesnt yet have support for it):
const isKeyOfExactTable = <O extends object, T extends string | number>(o: O, key: T): key is ??? => Object.hasOwnProperty.call(o, key);
// what to put here? -------------------------------------------------------------------------^^^
一直存在 JS 对象属性只能是字符串的问题,但每个成员访问都隐式转换数字。因此,TS 属性实际上可以是数字,即使不是,问题也会出现在成员访问时,只是提前一步。
从 TS 4.1 开始,模板文字类型解决了一个方向,这使得这几乎完全可能(如果任一侧有数字文字,则可以转换并检查),如果属性具有 number 索引,则可以取键中的所有数字。可悲的是,如果键是number,并且对象具有字符串作为属性,代表数字,那么似乎根本没有办法。甚至可以检查,确实有问题:
type HasStringNumber<T> = T extends `${number}`
? 'houston, we have a problem'
: 'all systems green';
type Test<O extends object, K extends string | number> = number extends K
? HasStringNumber<keyof O>
: 'all systems green';
但无法识别实际数字,例如这或多或少可以推断输入字符串:
type WhatNumber<T extends string> = T extends `${infer N}` ? N : 'Not a number';`
直接给出问题的输入/输出示例:
declare const o: { '1': 0 };
declare const k: number;
if (isKeyOfExactTable(o, k)) { /* typeof k is 1 */ }
【问题讨论】:
-
@Sisir 不,这不是该主题的欺骗 - 这是关于类型的。具有
typescript标签而不是javascript的链接主题无论如何都是一个笑话,因为它实际上是一个javascript问题(第一个答案甚至以“与javascript 完全一样”开头)。我将添加免责声明,以帮助忙碌的人更快地识别差异。
标签: typescript