英文:
How to create a type for any string value that is located in array of objects by property name?
问题
interface Icon {
id: number,
className: string,
tags: string[]
}
const iconArr = [
{
id: 1,
className: 'banana-class',
tags: ['']
},
{
id: 2,
className: 'apple-class',
tags: ['']
}
];
我想创建一个“type”,如果除了“banana-class”或“apple-class”之外的任何值被写入,将引发错误。
在字符串数组中,我会使用`type iconStringType = typeof iconStringArr[number]`,但在我的情况下,我有一个对象数组。
谢谢!
我尝试使用:
type iconType = typeof iconArr[number]['className'];
但它不起作用 - 它允许任何字符串值。
英文:
interface Icon {
id: number,
className: string,
tags: string[]
}
const iconArr = [
{
id: 1,
className: 'banana-class',
tags: ['']
},
{
id: 2,
className: 'apple-class',
tags: ['']
}
];
I would like to create a type that will cause an error if any other value other than banana-class or apple-class is written.
In array of strings i would use type iconStringType = typeof iconStringArr[number], but in my case i have an array of objects.
Thanks!
I tried using:
type iconType = typeof iconArr[number]['className'];
but it doesn't work - it allows any string value.
答案1
得分: 2
首先,你没有为你的 iconArr 数组设置类型,所以不管你的 Icon 接口如何定义,iconArr[number]['className'] 的类型都会被推断为 string。
你可以通过明确设置 Icon[] 类型来轻松解决这个问题,如下所示:
const iconArr: Icon[] = [
...
];
然后,如果你想要对 className 中允许的字符串进行严格限制,你可以创建一个联合类型 'banana-class' | 'apple-class' 并在 Icon 接口中使用它,如下所示:
interface Icon {
id: number,
className: 'banana-class' | 'apple-class',
tags: string[]
}
现在,你的 type iconType = typeof iconArr[number]['className'] 将评估为你创建的联合类型。
在评论中澄清后进行编辑:
如果你希望在运行时推断 Icon 类型,你可以这样做:
const iconArr = [
{
id: 1,
className: 'banana-class' as const,
tags: ['']
},
{
id: 2,
className: 'apple-class' as const,
tags: ['']
}
];
type Icon = typeof iconArr[number];
type iconType = typeof iconArr[number]['className'];
例如,使用 'apple-class' as const 声明告诉 TypeScript 推断“最狭窄的类型”,在你的情况下是 'banana-class' | 'apple-class'(参考文档)。
英文:
First of all, you don't type you iconArr array so the type iconArr[number]['className'] is inferred as string regardless of your Icon interface.
This can easily be fixed by explicitly setting the Icon[] type like:
const iconArr: Icon[] = [
...
];
Then if you want to be strict on the allowed strings in your className you could create a union type 'banana-class' | 'apple-class' and use it in your Icon interface:
interface Icon {
id: number,
className: 'banana-class' | 'apple-class',
tags: string[]
}
Now your type iconType = typeof iconArr[number]['className'] will evaluate to the union type you created.
Edit after clarification in comments:
If you want the Icon type inferred at runtime you can:
const iconArr = [
{
id: 1,
className: 'banana-class' as const,
tags: ['']
},
{
id: 2,
className: 'apple-class' as const,
tags: ['']
}
];
type Icon = typeof iconArr[number];
type iconType = typeof iconArr[number]['className'];
Defining e.g. 'apple-class' as const tells Typescript to infer the "narrowest type" which in your case is 'banana-class' | 'apple-class' (see docs)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论