[英]How can I generate a type from the properties values of a typed object in Typescript?
Say I had an interface
that described a library that items that look like this:假设我有一个
interface
,该界面描述了一个库,其中的项目如下所示:
interface MyItem {
category: string,
title: string
}
Now I have a config file full of those MyItems:现在我有一个包含这些 MyItems 的配置文件:
const myLibrary: MyItem[] = [
{
category: "dogs",
title: "Fuzzy quadrupeds"
},
{
category: "snakes",
title: "Slithery reptiles"
},
...
]
Now, I'd like to create a type that consists of all the category
in MyItem[]
现在,我想创建一个包含
MyItem[]
中所有category
的类型
If I do this: type Category = typeof MyItem[number]["category"]
I get string
.如果我这样做:
type Category = typeof MyItem[number]["category"]
我得到string
。
If I remove the typing from myLibrary
(ie const myLibrary = [ {...} ]
) and get what I want:如果我从
myLibrary
中删除输入(即const myLibrary = [ {...} ]
)并得到我想要的:
That means that type Category = typeof MyItem[number]["category"]
gives me the union type I want of dogs | snakes
这意味着
type Category = typeof MyItem[number]["category"]
给了我我想要的dogs | snakes
dogs | snakes
but of course I lose the typing when creating new items in my config file. dogs | snakes
,但当然我在我的配置文件中创建新项目时会丢失打字。
We want to restrict the items in myLibrary
such that they must implement MyItem
, but we want to do it in a way that preserves specific types of specific items and doesn't broaden the type to just MyItem
.我们希望限制
myLibrary
中的项目,以便它们必须实现MyItem
,但我们希望以保留特定项目的特定类型并且不将类型扩大到仅MyItem
的方式来做到这一点。
It is hard to do that just with assigning a type to the constant.仅通过为常量分配类型很难做到这一点。 A commonly-used pattern is to create the constant through an identity function.
一种常用的模式是通过标识 function 创建常量。 With a function we can use
extends
syntax to ensure that T extends MyItem[]
while keeping T
specific.使用 function 我们可以使用
extends
语法来确保T extends MyItem[]
同时保持T
特定。
I had to use as const
to get the literal category names, so I also had to allow readonly
in the function arguments.我必须使用
as const
来获取文字类别名称,所以我还必须在 function arguments 中允许readonly
。
interface MyItem {
category: string,
title: string
}
const buildLibrary = <T extends readonly MyItem[]>(library: T): T => library;
const myLibrary = buildLibrary([
{
category: "dogs",
title: "Fuzzy quadrupeds"
},
{
category: "snakes",
title: "Slithery reptiles"
}
] as const);
type Categories = (typeof myLibrary)[number]['category'] // "dogs" | "snakes"
If I understand you right, you want this: How to create enum like type in TypeScript?如果我理解正确,你想要这个: How to create enum like type in TypeScript? and then specify MyItem as
然后将 MyItem 指定为
interface MyItem: {
category: MyDogSnakeType,
title: string
}
Do not complicate不要复杂化
type Categorías = 'Food' | 'categoy1' | 'cstegory2'
interface MyItem {
category: Categories;
title: string
}
const myLibrary: MyItem[] = [
{
category: "dogs",
title: "Fuzzy quadrupeds"
},
{
category: "snakes",
title: "Slithery reptiles"
},
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.