[英]How to exhaustive check the elements in an array in typescript?
Given that I can use a Record
to make me not forget to type all options in an object鉴于我可以使用
Record
让我不会忘记在 object 中键入所有选项
type Country = "uk" | "france" | "india";
export const data: Record<Country, boolean> = {
uk: true,
france: true,
// complains that india is not present, excellent!
};
how can I make so it complains the same way for arrays?我怎样才能让它以同样的方式抱怨 arrays?
export const data = [
{value: "uk"},
{value: "france"},
// how to make typescript complain here that I forgot to add {value: "india"}?
];
Based on this answer , I think that this solves your problem:基于这个答案,我认为这可以解决您的问题:
type Country = "uk" | "france" | "india";
type MapOfKeysOf<U extends string> = {
[key in U]: MapOfKeysOf<Exclude<U, key>>;
}
type ExhaustiveArrayOfObjects<Keys extends {[key: string]: {}}, T = {}, KeyName extends string = "value"> = {} extends Keys ? [] : {
[key in keyof Keys]: [T & Record<KeyName, key>, ...ExhaustiveArrayOfObjects<Keys[key], T, KeyName>];
}[keyof Keys]
export const data: ExhaustiveArrayOfObjects<MapOfKeysOf<Country>> = [
{
value: 'uk',
},
{
value: 'france',
},
{
value: 'india',
}
]
If you want, you can pass an extra type to extends or event customize the prop that will hold de value如果你愿意,你可以传递一个额外的类型来扩展或事件自定义将保持价值的道具
type Country = "uk" | "france" | "india";
type MapOfKeysOf<U extends string> = {
[key in U]: MapOfKeysOf<Exclude<U, key>>;
}
type ExhaustiveArrayOfObjects<Keys extends {[key: string]: {}}, T = {}, KeyName extends string = "value"> = {} extends Keys ? [] : {
[key in keyof Keys]: [T & Record<KeyName, key>, ...ExhaustiveArrayOfObjects<Keys[key], T, KeyName>];
}[keyof Keys]
type Option = {
label: string,
id: Country
}
const data: ExhaustiveArrayOfObjects<MapOfKeysOf<Country>, Option, "id"> = [
{
label: "United Kingdom",
id: 'uk',
},
{
label: "France",
id: 'france',
},
{
label: "India",
id: 'india',
}
]
const option: Option = data[0]
You can check more on this playgroud你可以在这个游乐场上查看更多
I am using some utility functions from a library but the it is total achievable without using one.我正在使用库中的一些实用函数,但它完全可以在不使用一个的情况下实现。 I actually got some help from stack overflow in order to come up with this solution haha... Credits to caTS Related question
实际上,为了想出这个解决方案,我从堆栈溢出中得到了一些帮助哈哈...致谢caTS Related question
import { List, Union } from "ts-toolbelt";
type GetData<TCountries extends string[]> = List.Length<TCountries> extends 0
? []
: List.Append<GetData<List.Pop<TCountries>>, {
value: List.Last<TCountries>
}>;
export const data : GetData<Union.ListOf<Country>> = [
{value: "uk"},
{value: "france"},
// how to make typescript complain here that I forgot to add {value: "india"}?
];
I know it's ugly, but it's not factorial complexity and it does not require a helper function.我知道这很丑陋,但它不是阶乘复杂度,也不需要助手 function。
type Country = "uk" | "france" | "india";
const data = [
{ value: 'uk' },
{ value: 'france' },
{ value: 'india' }
] as const;
type test = IsExhaustive<typeof data>
type IsExhaustive<
T extends Country extends Values ? unknown : { error: [Country, 'does not extend', Values] },
Values = keyof {
[K in keyof T as T[K] extends {value: PropertyKey} ? T[K]['value'] : never]: never
}
> = T
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.