如何确保 TypeScript 中的对象值包含它们的键?

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

How to ensure object values contain their key with TypeScript?

问题

使用TypeScript的文字类型,我能够确保对象值由Color和字符串-primary组成。

type Color = "green" | "blue" | "orange" | "red" | "purple" | "pink";
type ColorObject<Key extends string = Color> = Record<Key, `${Key}-primary">;

const COLORS: ColorObject = {
    green: "green-primary",
    blue: "blue-primary",
    orange: "orange-primary",
    red: "red-primary",
    purple: "purple-primary",
    pink: "pink-primary"
};

但我想确保值与键相同,即:

pink: "pink-primary" // 好
pink: "red-primary" // 不好

我进行了相当多的搜索,不确定在我写这个回答的时候是否可能... 有什么想法吗?

英文:

Using TypeScript literal type, I'm able to ensure that the object values are made of a Color and the string -primary.

type Color = &quot;green&quot; | &quot;blue&quot; | &quot;orange&quot; | &quot;red&quot; | &quot;purple&quot; | &quot;pink&quot;;
type ColorObject&lt;Key extends string = Color&gt; = Record&lt;Key, `${Key}-primary`&gt;;

const COLORS: ColorObject = {
    green: &quot;green-primary&quot;,
    blue: &quot;blue-primary&quot;,
    orange: &quot;orange-primary&quot;,
    red: &quot;red-primary&quot;,
    purple: &quot;purple-primary&quot;,
    pink: &quot;pink-primary&quot;
};

But I would like to ensure that the value is the same as the key, i.e:

pink: &quot;pink-primary&quot; // good
pink: &quot;red-primary&quot; // bad

I searched quite a lot, not sure it's possible as the time I write this... Any ideas?

答案1

得分: 3

你应该使用mapped types来实现这个目标。在你当前的实现中,你的类型允许任何字符串颜色具有值中的任何颜色。相反,通过使用映射类型,我们将分别映射颜色并为它们分配相应的值:

type Color = 'green' | 'blue' | 'orange' | 'red' | 'purple' | 'pink';
type ColorObject<Key extends string = Color> = {
  [K in Key]: `${K}-primary`;
};

const COLORS: ColorObject = {
  green: 'green-primary',
  blue: 'orange-primary', // 预期错误
  orange: 'orange-primary',
  red: 'red-primary',
  purple: 'purple-primary',
  pink: 'pink-primary',
};

playground


<details>
<summary>英文:</summary>

You should use [mapped types](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html) to achieve it. In your current implementation, your type allows any string color to have any of the colors in the value. Instead by using mapped typed we will map through the colors separately and assign the corresponding value to them:

type Color = 'green' | 'blue' | 'orange' | 'red' | 'purple' | 'pink';
type ColorObject<Key extends string = Color> = {
[K in Key]: ${K}-primary;
};

const COLORS: ColorObject = {
green: 'green-primary',
blue: 'orange-primary', // expected error
orange: 'orange-primary',
red: 'red-primary',
purple: 'purple-primary',
pink: 'pink-primary',
};


[playground](https://www.typescriptlang.org/play?ts=5.0.4#code/C4TwDgpgBAwg9gGzgJygXigcgObIhAO0ygB8sAjBAVwmLMxQEMDtbSs8ATOrMK5MAjb0wASwIBrTAG4AUKEixEKAPLkAVhADGwADwBpCCCgQAHsEKcAzlCvBk47OiVJkAPmcBvWVCgBtfShxKEMQAF0ALigAAwAST30AXwBaMAcAW0ZkEGi5RLlZLTgCO1gVABkVACUAZSj4VzVNHS8fKFx8AiicPEJUjKyQTAAaNsoabqYWCH7RTOyRqAB6JZNTSB0IThNkZBQ2qdZJ5GZWWfmh0d8ubq5zwZG2vgEhbufBGbS5h6uoMUk3uIJPcFqN8rIgA)

</details>



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

发表评论

匿名网友

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

确定