英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论