英文:
How to infer object keys
问题
以下是代码部分的中文翻译:
// 创建一个对象,通过遍历数组并只选择需要的元素。示例将更清晰:
const items = [{ type: 'foo' }, { type: 'bar' }, { type: 'baz' }] as const
type MyItems = {
foo: string | null
bar: string | null
}
const myItems: MyItems = {
foo: null,
bar: null,
}
items.forEach(item => {
if (item.type in myItems) {
item.type
// ^? (属性) type: "foo" | "bar" | "baz"
}
if (Object.keys(myItems).includes(item.type)) {
item.type
// ^? (属性) type: "foo" | "bar" | "baz"
}
})
请注意,这是代码的中文翻译部分。如果您有任何其他问题或需要进一步的帮助,请随时告诉我。
英文:
I'm trying to create an object by iterating through an array and only picking the elements that I need. An example will make this clearer:
const items = [{ type: 'foo' }, { type: 'bar' }, { type: 'baz' }] as const
type MyItems = {
foo: string | null
bar: string | null
}
const myItems: MyItems = {
foo: null,
bar: null,
}
items.forEach(item => {
if (item.type in myItems) {
item.type
// ^? (property) type: "foo" | "bar" | "baz"
}
if (Object.keys(myItems).includes(item.type)) {
item.type
// ^? (property) type: "foo" | "bar" | "baz"
}
})
My real life example is more complexe and I can't simply reduce on items
.
My issue is that TypeScript doesn't infer properly on item.type after the condition and I don't know how to fix this other that with an as
that I'd rather not use if possible.
Is there another way of doing this?
答案1
得分: 1
你可以在迭代之前使用type guard function来过滤项目:
items.filter(pickByMyItems).forEach(item => {
if (item.type in myItems) {
item.type
// ^? (属性) type: "foo" | "bar"
}
if (Object.keys(myItems).includes(item.type)) {
item.type
// ^? (属性) type: "foo" | "bar"
}
})
你也可以在if条件中使用它:
items.forEach(item => {
if (pickByMyItems(item)) {
item.type
// ^? (属性) type: "foo" | "bar"
}
})
英文:
You can use a type guard function
const pickByMyItems =
<T extends (typeof items)[number]>(item: T): item is Extract<T, { type: keyof typeof myItems }> =>
Object.keys(myItems).includes(item.type)
to filter the items before iterating them:
items.filter(pickByMyItems).forEach(item => {
if (item.type in myItems) {
item.type
// ^? (property) type: "foo" | "bar"
}
if (Object.keys(myItems).includes(item.type)) {
item.type
// ^? (property) type: "foo" | "bar"
}
})
--
you can as well use it in an if condition
items.forEach(item => {
if (pickByMyItems(item)) {
item.type
// ^? (property) type: "foo" | "bar"
}
})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论