来自自己的动态界面 属性
Dynamic Interface from own property
我想知道这在 TypeScript 上是否可行。
我有这样的界面:
interface ComplexTable extends BaseTable {
headers: HeaderOptions[];
datas: { [id: string]: string }[];
}
而 HeaderOptions 只是一个带有标签和 id 的接口
有没有办法只允许数据 headers 之前给出的 ID?
比如我有
const table: ComplexTable = {
headers: [
{ id: 'a', label: 'Name' },
{ id: 'b', label: 'Last Name' },
]
}
我不想只允许在数据 objects 上只使用键 'a' 和 'b'。
这应该有效
const table: ComplexTable = {
headers: [
{ id: 'a', label: 'Name' },
{ id: 'b', label: 'Last Name' },
],
datas: someData.map((data) => ({
a: data.someValue,
b: data.someOtherValue
}))
}
这应该行不通
const table: ComplexTable = {
headers: [
{ id: 'a', label: 'Name' },
{ id: 'b', label: 'Last Name' },
],
datas: someData.map((data) => ({
a: data.someValue,
c: data.someOtherValue
}))
}
你可以做到这一点,但这需要一些工作:
- 您需要参数化
ComplexTable
,以便它可以将相同的规则应用于其成员 headers
和 datas
。
- 您需要参数化
HeaderOptions
以便它可以从 id
中读取密钥,而不是将它们视为普通的 string
。
- 您需要指定
datas
才能使用 mapped type [id in K]
。
- 在构建 table.
时,您需要一个恒等函数
看起来像这样:
interface HeaderOptions<K> {
id: K;
label: string;
}
interface ComplexTable<K extends string> extends BaseTable {
headers: HeaderOptions<K>[];
datas: { [id in K]: string }[];
}
function complexTable<K extends string>(table: ComplexTable<K>) {
return table;
}
所以你可以像这样调用它:
const shouldWork = complexTable({
headers: [
{ id: 'a', label: 'Name' },
{ id: 'b', label: 'Last Name' },
],
datas: someData.map((data) => ({
a: data.someValue,
b: data.someOtherValue
}))
});
请注意,就像在 playground 中一样,TypeScript 不会介意您提供的数据键多于它在 headers
中预期的数据键;但是,如果缺少任何数据键,它会抱怨。
我想知道这在 TypeScript 上是否可行。
我有这样的界面:
interface ComplexTable extends BaseTable {
headers: HeaderOptions[];
datas: { [id: string]: string }[];
}
而 HeaderOptions 只是一个带有标签和 id 的接口
有没有办法只允许数据 headers 之前给出的 ID?
比如我有
const table: ComplexTable = {
headers: [
{ id: 'a', label: 'Name' },
{ id: 'b', label: 'Last Name' },
]
}
我不想只允许在数据 objects 上只使用键 'a' 和 'b'。
这应该有效
const table: ComplexTable = {
headers: [
{ id: 'a', label: 'Name' },
{ id: 'b', label: 'Last Name' },
],
datas: someData.map((data) => ({
a: data.someValue,
b: data.someOtherValue
}))
}
这应该行不通
const table: ComplexTable = {
headers: [
{ id: 'a', label: 'Name' },
{ id: 'b', label: 'Last Name' },
],
datas: someData.map((data) => ({
a: data.someValue,
c: data.someOtherValue
}))
}
你可以做到这一点,但这需要一些工作:
- 您需要参数化
ComplexTable
,以便它可以将相同的规则应用于其成员headers
和datas
。 - 您需要参数化
HeaderOptions
以便它可以从id
中读取密钥,而不是将它们视为普通的string
。 - 您需要指定
datas
才能使用 mapped type[id in K]
。 - 在构建 table. 时,您需要一个恒等函数
看起来像这样:
interface HeaderOptions<K> {
id: K;
label: string;
}
interface ComplexTable<K extends string> extends BaseTable {
headers: HeaderOptions<K>[];
datas: { [id in K]: string }[];
}
function complexTable<K extends string>(table: ComplexTable<K>) {
return table;
}
所以你可以像这样调用它:
const shouldWork = complexTable({
headers: [
{ id: 'a', label: 'Name' },
{ id: 'b', label: 'Last Name' },
],
datas: someData.map((data) => ({
a: data.someValue,
b: data.someOtherValue
}))
});
请注意,就像在 playground 中一样,TypeScript 不会介意您提供的数据键多于它在 headers
中预期的数据键;但是,如果缺少任何数据键,它会抱怨。