【问题标题】:How to restrict possible value of index type?如何限制索引类型的可能值?
【发布时间】:2021-09-27 17:41:41
【问题描述】:

我们可以声明index signature来强制对象的属性为特定类型,如下所示

const LOOKUP: {
  [key: string]: { name: string, age: number };
} = {
  isaac: { name: 'isaac', age: 20 },
  whatever: {name: 'whatever', age: 17}
};

但是,我想限制key 的可能值,所以下面是我的尝试

尝试 1

type PossibleName = 'isaac' | 'john';

const LOOKUP: {
  [key: PossibleName]: { name: string, age: number };
} = {
  isaac: { name: 'isaac', age: 20 },
  whatever: {name: 'whatever', age: 17}
};

上面的尝试碰到下面的错误

索引签名参数类型不能是文字类型或泛型类型。考虑改用映射对象类型。

尝试 2

type PossibleName = 'isaac' | 'john';

const LOOKUP: {
  [key in PossibleName]: { name: string, age: number };
} = {
  isaac: { name: 'isaac', age: 20 },
};

并且尝试 2 在下面遇到错误

类型 '{ isaac: { name: string; 中缺少属性 'john'年龄:数字; }; }' 但在 '{ isaac: { name: string; 类型中是必需的年龄:数字; };约翰:{名称:字符串;年龄:数字; }; }'

我可以通过使键可选如下来解决它

type PossibleName = 'isaac' | 'john';

const LOOKUP: {
  [key in PossibleName]?: { name: string, age: number };
} = {
  isaac: undefined,
};

它确实允许不声明john,但同时允许isaacjohn 的值undefined,这不是我想要的。

我的目标是,如果我定义了isaacjohn,则值不应接受undefined,而必须是{ name: string, age: number} 类型,想知道这是否可能?

【问题讨论】:

  • “这不是我想要的” 那你想要什么?
  • @FelixKling:我的想法是,如果我定义了Isaacjohn,则该值不应接受undefined,但必须是{ name: string, age: number} 类型,想知道是否这可能吗?
  • 从实际运行时的角度来看,{}john: undefined 之间没有区别。使某些东西成为可选项与允许其值为undefined 相同。
  • @FelixKling:同意,但是从代码可维护性的角度来看,如果他们将undefined 分配给道具,我想向开发人员抛出错误,因为undefined 是一个有效值。正是为什么我觉得[key in PossibleName]? 听起来很奇怪,因为我真的不想让它成为可选值,而是限制可能的值
  • 那么你想要的是{john: Person} | {isaac: Person}之类的东西?还是{john: Person} | {isaac: Person} | {john: Person, isaac: Person}

标签: javascript typescript


【解决方案1】:
type PossibleName = 'isaac' | 'john';
type Person = { name: string }
type MyType = {
  [K in PossibleName]: { [k in K]: Person }
}[PossibleName] | { [K in PossibleName]: Person }

不好看,随便找个办法滥用TS引擎。这将产生{john: Person} | {isaac: Person}| {isaac: Person; john: Person}

Playground

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 2015-05-31
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 2017-04-14
  • 1970-01-01
  • 2019-07-14
相关资源
最近更新 更多