don*_*don 18 typescript typescript-typings
我这样定义AbstractModel:
export interface AbstractModel {
[key: string]: any
}
Run Code Online (Sandbox Code Playgroud)
然后我宣布类型Keys:
export type Keys = keyof AbstractModel;
Run Code Online (Sandbox Code Playgroud)
我希望任何具有Keys类型的东西都可以单义地解释为字符串,例如:
const test: Keys;
test.toLowercase(); // Error: Property 'toLowerCase' does not exist on type 'string | number'. Property 'toLowerCase' does not exist on type 'number'.
Run Code Online (Sandbox Code Playgroud)
这是一个Typescript(2.9.2)的错误,还是我错过了什么?
jma*_*eis 24
如TypeScript 2.9的发行说明中所定义,如果您使用字符串索引签名键入接口,则返回字符串和数字的并集
给定对象类型X,keyof X解析如下:
如果X包含字符串索引签名,则keyof X是字符串,数字和表示符号类属性的文字类型的并集,否则
如果X包含数字索引签名,则keyof X是数字和文字类型的并集,表示类似字符串和符号的属性,否则
keyof X是表示类似字符串,类似数字和类似符号的属性的文字类型的并集.
这是因为:JavaScript在索引对象时将数字转换为字符串:
[...]在使用数字进行索引时,JavaScript实际上会在索引到对象之前将其转换为字符串.这意味着使用100(数字)索引与使用"100"(字符串)进行索引相同,因此两者需要保持一致.
例:
let abc: AbstractModel = {
1: "one",
};
console.log(abc[1] === abc["1"]); // true
Run Code Online (Sandbox Code Playgroud)
当您只需要字符串键时,您只能从界面中提取字符串键,如下所示:
type StringKeys = Extract<keyof AbstractModel, string>;
const test: StringKeys;
test.toLowerCase(); // no error
Run Code Online (Sandbox Code Playgroud)
此外,TypeScript编译器提供了一个选项来获取前2.9的行为keyof:
keyofStringsOnly(boolean)默认值
false仅解析
keyof为字符串值属性名称(无数字或符号).
我也遇到过类似的问题。我通过将key强制为字符串来解决它:
export type Keys = keyof AbstractModel & string;
Run Code Online (Sandbox Code Playgroud)
另一种选择是将密钥转换为字符串: test.toString().toLowercase()
对于通用打字稿实用程序,您可以使用以下内容:
type KeyOf<T extends object> = Extract<keyof T, string>;
Run Code Online (Sandbox Code Playgroud)
用法:
const sym = Symbol();
const obj = {
[sym]: true,
foo: 'foobar',
bar: 'barfoo',
1: 'lorem'
}
let key: KeyOf<typeof obj> = 'foo'; // 'foo' | 'bar'
key = 'bar'; // ok
key = 'fool'; // error
key = 1; // error
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3872 次 |
| 最近记录: |