简体   繁体   English

如何强制密钥为字符串类型(而不是数字或符号)?

[英]How can I enforce a key to be of type string (and not number or symbol)?

I want to create a type for an object with string keys and arbitrary values.我想用string键和任意值为 object 创建一个类型。 Thus, my desired type (let's call it Obj ) should cause a type error for the following obj object because its key is of type number :因此,我想要的类型(我们称之为Obj )应该会导致以下obj object 的类型错误,因为它的键是number类型:

const obj: Obj = {
    1: "foo" // I'd expect a TS error here because the key 1 is of type `number` and not `string`
};

However, all of my attempts don't cause any TS error: Here are my three attempts:但是,我的所有尝试都不会导致任何 TS 错误:这是我的三个尝试:

  1. Built-in Record type (which implicitly uses the in operator):内置Record类型(隐式使用in运算符):
type Obj = Record<'1', any>;

const obj: Obj = {
    1: "foo" // TS error expected! ❌
};
  1. Mapped type (to recreate Record type):映射类型(重新创建Record类型):
type Obj = { [key: string]: any };

const obj: Obj = {
    1: "foo" // TS error expected! ❌
};
  1. Custom Record type with key remapping via as : 通过as进行键重新映射的自定义Record类型:
type MyRecord<K extends string, T> = {
    [P in K as string]: T;
};
type Obj = MyRecord<string, any>;

const obj: Obj = {
    1: "foo" // TS error expected! ❌
};
  1. Even using a literal type '1' does not enforce the key to be '1' , but allows the number 1 :即使使用文字类型'1'也不会强制'1' ,但允许数字1
type Obj = Record<'1', any>;

const obj: Obj = {
    1: "foo" // TS error expected! ❌
};

Is it in general possible, or is it due to some property of a JavaScript object that it's not possible?通常是可能的,还是由于 JavaScript object 的某些属性,这是不可能的?

TS Playground of my code . 我的代码的 TS Playground

The 1 is coerced to a string ( "1" ) when defining an object literal.在定义 object 文字时, 1被强制转换为string ( "1" )。 You cannot define an object with number keys:您不能使用number键定义 object:

 const obj = { prop: 'value', 1: 'another value', }; for (const key in obj) { console.log(key, typeof key); }

By thekeyof page of TypeScript doc通过keyof doc 页面的键

JavaScript object keys are always coerced to a string, so obj[0] is always the same as obj["0"] JavaScript object 键总是被强制为字符串,所以 obj[0] 总是和 obj["0"] 一样

So in fact {1: "foo"} is just as same as {"1": "foo"} .所以实际上{1: "foo"}{"1": "foo"}是一样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM