如何强制 TypeScript 允许将 null 作为索引类型?

huangapple go评论79阅读模式
英文:

How to force TypeScript to allow null as an index type?

问题

我有一个位于大型项目中的对象,它将null用作键,并且无法更改,因为这将破坏应用程序中的所有内容。

但是,我到处都收到Type null cannot be used as an index type. ts(2538)的错误。有没有办法告诉TypeScript接受null作为对象键,就像它接受数字键一样?

demo

英文:

I have an object inside a large project that uses null as a key and that cannot be changed, since it would break things all over the app.

However, I'm getting Type null cannot be used as an index type. ts(2538) all over the place. Is there a way to tell TypeScript to accept null as an object key the same way it accepts numbers as keys?

demo

答案1

得分: 2

All keys in javascript are converted to strings or symbols. Even if assigned non string values, the keys are converted to string.

So MyObject[null] should become something like MyObject['null'] and should work as is. All you have to do is use 'null' (as a string) instead of null when accessing the property.

Note that there is another change required. The below statement means that key can be assgined any string value or the value null.

const key: string | null = null;

But MyObject only has three valid keys a,b,null. So you should modify your statement like:

const key: keyof typeof MyObject  = 'null';

or

const key  = 'null';

So, key can only be assigned valid MyObject keys.

const MyObject = {
    null: 0,
    a: 1,
    b: 2,
}

//const key: keyof typeof MyObject  = 'null';
const key = 'null';

console.log(MyObject[key]);

Playground

英文:

All keys in javascript are converted to strings or symbols. Even if assigned non string values, the keys are converted to string.

So MyObject[null] should become something like MyObject['null'] and should work as is. All you have to do is use 'null' (as a string) instead of null when accessing the property.

Note that there is another change required. The below statement means that key can be assgined any string value or the value null.

const key: string | null = null;

But MyObject only has three valid keys a,b,null. So you should modify your statement like:

const key: keyof typeof MyObject  = 'null';

or

const key  = 'null';

So, key can only be assigned valid MyObject keys.

const MyObject = {
    null: 0,
    a: 1,
    b: 2,
}

//const key: keyof typeof MyObject  = 'null';
const key = 'null';

console.log(MyObject[key]);

Playground

答案2

得分: 1

在TypeScript中,当将对象用作索引类型时,类型系统会强制要求索引必须可以分配给stringnumber。这就是为什么你会收到错误消息Type null cannot be used as an index type的原因。

不幸的是,没有直接告诉TypeScript接受null作为有效索引类型的方法,除非修改TypeScript编译器或更改对象的定义。

然而,如果修改对象不是选项,你可以通过使用类型断言(as)来暂时覆盖类型检查来解决此问题。以下是一个示例:

const MyObject = {
    null: 0,
    a: 1,
    b: 2,
};

const key: string | null = null;

console.log(MyObject[key as keyof typeof MyObject]); // 使用类型断言绕过类型检查

通过使用key as keyof typeof MyObject,你实际上告诉TypeScript将key视为MyObject对象的有效键。但是,请记住,这会绕过类型检查,因此你需要确保key在运行时是有效的键;否则,可能会遇到运行时错误。

英文:

In TypeScript, when using an object as an index type, the type system enforces that the index must be assignable to string or number. That's why you're getting the error Type null cannot be used as an index type.

Unfortunately, there is no way to directly tell TypeScript to accept null as a valid index type without modifying the TypeScript compiler or changing the definition of the object.

However, if modifying the object is not an option, you can work around this issue by using a type assertion (as) to override the type checking temporarily. Here's an example:

const MyObject = {
    null: 0,
    a: 1,
    b: 2,
};

const key: string | null = null;

console.log(MyObject[key as keyof typeof MyObject]); // Use type assertion to bypass type checking

By using key as keyof typeof MyObject, you're essentially telling TypeScript to treat key as a valid key of the MyObject object. However, keep in mind that this bypasses type checking, so you need to ensure that key is a valid key at runtime; otherwise, you may encounter a runtime error.

答案3

得分: 0

在TypeScript中,他们积极决定仅允许字符串或数字类型作为索引签名。可能是因为大多数情况下,试图使用类似null这样的东西来索引对象的人通常表示存在错误。

在你的情况下,你可以像这样做:

function buildInverseMap(source: Array<string | null>): { [key: string]: number } {
    var inverseMap: { [key: string]: number } = {};
    for (let i = 0; i < source.length; i++) {
        inverseMap[String(source[i])] = i; // 自己强制转换为字符串
    }
    return inverseMap;
}     // 函数示例。

inverseMap[source[i] || "null"] = i;  // 对象示例。 

希望有所帮助!祝你好运。

英文:

So, in TypeScript they actively decided to only allow the string or number type as index signatures. Probably because most of the time, anyone trying to index into an object using something like null is indicative of an error.

In your case, you can do something like this:

function buildInverseMap(source: Array&lt;string | null&gt;) : {[key: string] : number} {
    var inverseMap: { [key: string]: number } = {};
    for (let i = 0; i &lt; source.length; i++) {
        inverseMap[String(source[i])] = i; // coerce to string yourself
    }
    return inverseMap;
}     // example for function.

inverseMap[source[i] || &quot;null&quot;] = i;  // example for an object. 

Hope that helps! Good luck.

huangapple
  • 本文由 发表于 2023年6月30日 01:17:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76583270.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定