我有一个界面专栏。
interface column {
field: string
label: string
}
所以一排列将是:
const cols = [{
label: 'First Name',
field: 'fname',
},
{
label: 'Last Name',
field: 'lname',
},
{
label: 'Email',
field: 'email',
}]
数据将是数据行的数组。
const data:{}[] = [{
fname: 'bob', lname: 'dylan', email: 'db@email.com',
fname: 'van', lname: 'halen', email: 'vh@email.com'
}]
有没有一种方法可以将数据的键(即[fname,lname,email])强制为相应cols [n] ['field']的值? 预先感谢。
答案 0 :(得分:1)
是的,只要您以这样的方式定义cols
,以使编译器不会将field
属性扩展为string
,就可以这样做。使用TS3.4 +的最简单方法是使用const
assertion:
const cols = [{
label: 'First Name',
field: 'fname',
},
{
label: 'Last Name',
field: 'lname',
},
{
label: 'Email',
field: 'email',
}] as const;
as const
意味着cols
将被视为只读元组,其中label
和field
属性具有string literal类型。
您可以在此处创建类型别名,该别名将Column
兼容的值集转换为以field
属性为键的对象类型。当然,没有提到每个字段的值类型是什么,因此我假设它始终为string
:
interface Column {
field: string
label: string
};
type StringObjFromColumns<T extends readonly Column[]> =
{ [K in T[number]["field"]]: string }
然后我们可以将您的数据类型定义为StringObjFromColumns<typeof cols>
:
const data: StringObjFromColumns<typeof cols>[] = [{
fname: 'bob', lname: 'dylan', email: 'db@email.com',
}, {
fname: 'van', lname: 'halen', email: 'vh@email.com'
}, {
fname: 'van', lname: 'morrison', age: 75, email: 'vm@example.com' // error! age is extra
}, {
fname: 'ted', lname: 'nugent' // error! email is missing
}]
您可以看到它如何强制每个对象必须具有string
类型的这三个字段的约束。
好的,希望能有所帮助;祝你好运!
答案 1 :(得分:0)
这是不可能的,因为打字稿类型是在编译时而不是运行时强制执行的。请参阅我对this question的回答,它会回答您的问题。
答案 2 :(得分:-1)
这是一个棘手的问题。
有
interface Column {
field: string
label: string
}
我们可以定义一个RowObject
,此外,仅出于示例目的,一个Row
具有column
属性和row
本身。
interface RowObject {
[key: string]: string;
}
interface Row {
cols: Column[];
object: RowObject;
}
现在,我们应该定义一个函数来原型化新对象。
const createRowBlueprint = (cols: Column[]): Row => {
return {
cols: [...cols],
object: cols.map(c => c.field)
.reduce((prop: RowObject, prev: string) => (prop[prev] = '', prop), {})
};
};
我刚刚定义了Row
接口来动态访问“真实行对象”属性,就像这样
const row = createRowBlueprint(cols);
row.cols.forEach(col => {
const { field } = col;
const value = row.object[field];
console.log(`Field ${field} binded to ${value}`);
});
鉴于您的columns
集合,将输出以下内容
{
cols: [
{ label: 'First Name', field: 'fname' },
{ label: 'Last Name', field: 'lname' },
{ label: 'Email', field: 'email' }
],
row: { fname: '', lname: '', email: '' }
}
Field fname binded to
Field lname binded to
Field email binded to
很明显,我将默认值设置为空字符串。但是,有效的证明是从字段访问的值不是undefined
。
最后,这种方法不是安全类型。但是,据我所知,Typescript目前暂时不支持动态类型定义。所以这是一个棘手的解决方法。
希望有帮助。