【问题标题】:Typescript: record of KeyType -> value types打字稿:KeyType -> 值类型的记录
【发布时间】:2021-11-29 08:36:32
【问题描述】:

我需要创建一个 Typescript Record,其中的键定义为独立类型和每个值的特定类型。

键定义如下:

// Keys must be available/iterable at runtime
const keys = ['a', 'b', 'c'] as const
export type Key = typeof keys[number]

现在我看到了两个选项,都是有缺陷的。

选项 1:根据需要重复键并明确定义值类型。缺陷:Structure 实际上并不是基于Key,它们可能会出现偏差。

export type Structure1 = {
  a: number
  b: boolean
  c: string
}

选项 2:从 Key 定义记录并丢失值的特定类型信息:

export type Structure2 = Record<Key, number | boolean | string>

对于使用Key 作为键类型每个键的显式值类型的Structure3,是否有第三种选择?

【问题讨论】:

  • 为什么第二个选项不好?
  • 因为Structure2 将接受booleanstringa
  • 您是否正在寻找将值类型定义为元组 ([number, boolean, string]) 并按顺序使用键“压缩”?
  • 在这种情况下你需要有一些地图类型
  • 然后你可以定义一个对象并从中提取类型和键typescriptlang.org/play?#code/…

标签: typescript record


【解决方案1】:

您可以保持 DRY 并像这样强制执行您的界面键(性能奖励:没有额外的运行时代码):

TS Playground link

type EnforceKeys<Key extends string, T extends Record<Key, unknown>> = {
  [K in keyof T as K extends Key ? K : never]: T[K];
};

const keys = ['a', 'b', 'c'] as const;
type Key = typeof keys[number];

// Ok
type Structure1 = EnforceKeys<Key, {
  a: number;
  b: boolean;
  c: string;
}>;

// Ok, and extra properties are omitted
type Structure2 = EnforceKeys<Key, {
  a: number;
  b: boolean;
  c: string;
  d: number[]; // omitted from type
  e: boolean; // omitted from type
}>;

// Error: Property 'c' is missing in type... (2344)
type Structure3 = EnforceKeys<Key, {
  a: number;
  b: boolean;
}>;

【讨论】:

    猜你喜欢
    • 2019-01-26
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 2020-03-09
    • 2021-11-26
    • 2015-11-06
    相关资源
    最近更新 更多