首页 > 解决方案 > TS 标记字符串作为对象的键

问题描述

想象一下,我有带有字符串标识符的类 Foo 。

class Foo {
    id = '123' as FooId;
}

我尝试使用品牌 enum确保它的静态类型。

enum FooIdBranding {}
type FooId = string & FooIdBranding;

所以现在,我的目标是特定对象,键在哪里,FooId值在哪里Foo

type fooCache = { [key: FooId]: Foo };

不幸的是,它不起作用:

TS1023:索引签名参数类型必须是“字符串”或“数字”

我想,记录是我的解决方案,但也不起作用。

type FooCache = Record<FooId, Foo>;

({} as FooCache)['123' as FooId] = new Foo();

TS 7017:元素隐式具有“任何”类型,因为类型Record<FooId, Foo>没有索引签名

TypeScript 中是否有解决此问题的正确方法?

标签: typescriptstatic-typing

解决方案


“符号和模板字符串模式索引签名”已添加到 TypeScript 4.4中,因此现在可以这样做。

type FooId = string & {brand: 'FooId'};
const id1 = '1' as FooId
const id2 = '2' as FooId

class Foo {
  constructor(public id: FooId) {}
}

type fooCache = { [key: FooId]: Foo };

const foo: fooCache = {
  // Type '{ key: Foo; }' is not assignable to type 'fooCache'.
  // Object literal may only specify known properties, and 'key' does not exist in type 'fooCache'.(2322)
  // (property) key: Foo
  key: new Foo(id1)
}

// All good
const bar: fooCache = {
  [id1]: new Foo(id1)
}

TS 操场上的示例。


推荐阅读