【问题标题】:Infer type from array value从数组值推断类型
【发布时间】:2020-06-05 19:20:43
【问题描述】:

使用 Typescript 3.8.3。

我正在尝试为以下数据设置类型,但我一生都无法弄清楚。

type Info = {
  title: string;
  description: string;
    items: Array<Item<object>>;
}

type Item<T> = {
  title: string;
  data: T;
}

const info: Info = {
  title: 'some title',
  description: 'some description',
  items: [
    { title: 'title1', data: { param1: 'something', param2: 'something else' } },
    { title: 'title2', data: { param3: 'abc' } },
    { title: 'title3', data: { param1: 'not the same as above, just the key name', param4: 123 } }
  ]
};

info.items[0].data.param1 // Property 'param1' does not exist on type 'object'

我知道Array&lt;Item&lt;object&gt;&gt; 是错误的,但我不知道如何推断元素数组的联合类型。

我想要实现的目标有可能吗?

【问题讨论】:

  • 你想在数据对象上允许什么样的参数?从字面上看是任何键/值对,还是有它们的特定列表?
  • 基本上我想要任何参数,这意味着我可以为它们创建类型,但我需要它易于扩展

标签: typescript typescript3.8


【解决方案1】:

你唯一能做的就是:

type Info = {
  title: string;
  description: string;
    items: ReadonlyArray<Item<object>>; // Only work with ReadonlyArray
}

type Item<T> = {
  title: string;
  data: T;
}

const info = {
  title: 'some title',
  description: 'some description',
  items: [
    { title: 'title1', data: { param1: 'something', param2: 'something else' } },
    { title: 'title2', data: { param3: 'abc' } },
    { title: 'title3', data: { param1: 'not the same as above, just the key name', param4: 123 } }
  ]
} as const;

info.items[0].data.param1 // 'something' as info type is known
const anotherInfo: Info = info // info const be assigned to Info

如果info不是'const'类型,你可以修改成:info.items = [],所以typescript不能保证info.items[0].data.param1的值/类型

【讨论】:

  • 谢谢,看来我不能像我想要的那样做,因为info 将被动态分配,而不是在编译时。
【解决方案2】:

这行得通吗?

type Info<T> = {
  title: string;
  description: string;
  items: Item<T>[];
}

type Item<T> = {
  title: string;
  data: T;
}

const info = {
  title: 'some title',
  description: 'some description',
  items: [
    { title: 'title1', data: { param1: 'something', param2: 'something else' } },
    { title: 'title2', data: { param3: 'abc' } },
    { title: 'title3', data: { param1: 'not the same as above, just the key name', param4: 123 } }
  ]
};

info.items[0].data.param1 // string | undefined

【讨论】:

  • 这只是完全忽略了Info 类型
猜你喜欢
  • 1970-01-01
  • 2021-11-05
  • 2022-01-02
  • 2021-08-05
  • 2021-08-20
  • 1970-01-01
  • 2018-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多