如何为对象的动态属性设置一个好的条件
How to set a good condition for dynamic property of object
我有一个对象数组:
export const inputsArray: InputAttributes[] = [
{
label: 'Name',
type: 'text',
name: 'name',
required: true
},
{
label: 'User name',
type: 'text',
name: 'username',
required: true
},
...
]
并像这样映射它:
const inputs = inputsArray.map(input => {
const value = (input.name === 'street' || input.name === 'city' || input.name === 'zipcode') // <= PROBLEM : NOT EFFECTIVE CONDITION!
? user?.address?.[input.name]
: user?.[input.name] // <= TYPESCRIPT PROBLEM
return (
<Input
key={input.name}
defaultValue={value}
input={input}
disabled={disabled}
onChange={hadndleChange}
/>
)
})
用户信息:
export interface User {
id: number,
name: string,
username: string,
email: string,
address: {
street: string,
city: string,
zipcode: string,
}
phone: string,
website: string,
company: {
name: string
}
}
- 如您所见,在 map 方法中我有一个值条件。但这并不好,因为如果用户对象在 address 或 company 或其他 属性 以对象为值的内部有更多附加属性,我需要在其中放置更多条件。有更好的模式吗?
user?.[input.name]
打字稿说“类型 'string' 不能用于索引类型 'Users'”。我可以通过在用户界面中设置 [key: string] : any
来避免这个问题,但是有没有更好的模式?
如果需要输入属性接口:
export interface InputAttributes {
label: string,
type: string,
name: string,
pattern?: string,
required: boolean
}
将值存储在数组中,然后使用 Array.prototype.some()
。这样您就可以支持任意数量的名称。
const names = ['street', 'zipcode', 'city'];
const value = names.some((name) => input.name === name) ? user?.address?.[input.name] : user?.[input.name];
你应该像这样修改InputAttributes
界面:
type DeepKeyOf<T> = {
[K in keyof T]: T[K] extends Record<string, any> ? DeepKeyOf<T[K]> : K
}[keyof T]
export interface InputAttributes {
label: string,
type: string,
name: DeepKeyOf<User>,
pattern?: string,
required: boolean
}
现在 TypeScript 知道 name
属性 必须包含 User
.
的一些键
我有一个对象数组:
export const inputsArray: InputAttributes[] = [
{
label: 'Name',
type: 'text',
name: 'name',
required: true
},
{
label: 'User name',
type: 'text',
name: 'username',
required: true
},
...
]
并像这样映射它:
const inputs = inputsArray.map(input => {
const value = (input.name === 'street' || input.name === 'city' || input.name === 'zipcode') // <= PROBLEM : NOT EFFECTIVE CONDITION!
? user?.address?.[input.name]
: user?.[input.name] // <= TYPESCRIPT PROBLEM
return (
<Input
key={input.name}
defaultValue={value}
input={input}
disabled={disabled}
onChange={hadndleChange}
/>
)
})
用户信息:
export interface User {
id: number,
name: string,
username: string,
email: string,
address: {
street: string,
city: string,
zipcode: string,
}
phone: string,
website: string,
company: {
name: string
}
}
- 如您所见,在 map 方法中我有一个值条件。但这并不好,因为如果用户对象在 address 或 company 或其他 属性 以对象为值的内部有更多附加属性,我需要在其中放置更多条件。有更好的模式吗?
user?.[input.name]
打字稿说“类型 'string' 不能用于索引类型 'Users'”。我可以通过在用户界面中设置[key: string] : any
来避免这个问题,但是有没有更好的模式?
如果需要输入属性接口:
export interface InputAttributes {
label: string,
type: string,
name: string,
pattern?: string,
required: boolean
}
将值存储在数组中,然后使用 Array.prototype.some()
。这样您就可以支持任意数量的名称。
const names = ['street', 'zipcode', 'city'];
const value = names.some((name) => input.name === name) ? user?.address?.[input.name] : user?.[input.name];
你应该像这样修改InputAttributes
界面:
type DeepKeyOf<T> = {
[K in keyof T]: T[K] extends Record<string, any> ? DeepKeyOf<T[K]> : K
}[keyof T]
export interface InputAttributes {
label: string,
type: string,
name: DeepKeyOf<User>,
pattern?: string,
required: boolean
}
现在 TypeScript 知道 name
属性 必须包含 User
.