如何高效将DomType与TextType的交集属性添加到textElement对象?
解决方案
方案1:手动指定交集属性列表(最高效)
既然TextType的属性是明确的,直接列出这些属性进行复制,避免不必要的遍历和判断,性能最优:
type DomType = { backgroundColor?: string, color?: string, padding?: string, margin?: string, display?: string, } let DomElement: DomType = { backgroundColor: 'red', color: 'green', padding: '5px', margin: '2px', display: 'flex' } type TextType = { backgroundColor?: string, color?: string, } let textElement: TextType = {}; // 直接列出TextType的属性,逐一复制 const textProps: Array<keyof TextType> = ['backgroundColor', 'color']; textProps.forEach(prop => { if (DomElement[prop] !== undefined) { textElement[prop] = DomElement[prop]; } }); console.log(textElement); // {backgroundColor: 'red', color: 'green'}
方案2:使用类型守卫实现动态判断
如果需要更灵活的方式(比如TextType可能变动),可以写一个类型守卫函数,在运行时判断键是否属于TextType的属性:
type DomType = { backgroundColor?: string, color?: string, padding?: string, margin?: string, display?: string, } let DomElement: DomType = { backgroundColor: 'red', color: 'green', padding: '5px', margin: '2px', display: 'flex' } type TextType = { backgroundColor?: string, color?: string, } let textElement: TextType = {}; // 类型守卫函数,收窄键的类型 function isTextProp(key: string): key is keyof TextType { return ['backgroundColor', 'color'].includes(key); } for (const key in DomElement) { if (isTextProp(key)) { textElement[key] = DomElement[key]; } } console.log(textElement); // {backgroundColor: 'red', color: 'green'}
方案3:结合TypeScript工具类型与运行时数组
利用Extract工具类型提取DomType和TextType的交集键,同时保证运行时数组和类型定义一致(TypeScript会做类型校验):
type DomType = { backgroundColor?: string, color?: string, padding?: string, margin?: string, display?: string, } let DomElement: DomType = { backgroundColor: 'red', color: 'green', padding: '5px', margin: '2px', display: 'flex' } type TextType = { backgroundColor?: string, color?: string, } let textElement: TextType = {}; // 提取两个类型的交集键类型 type IntersectionKeys = Extract<keyof DomType, keyof TextType>; // 运行时数组必须和类型对应,否则TypeScript会报错 const intersectionProps: IntersectionKeys[] = ['backgroundColor', 'color']; intersectionProps.forEach(prop => { if (DomElement[prop] !== undefined) { textElement[prop] = DomElement[prop]; } }); console.log(textElement); // {backgroundColor: 'red', color: 'green'}
原代码的问题原因
TypeScript的类型信息仅存在于编译阶段,运行时无法直接通过类型判断键的归属。原代码中key in DomElement得到的key类型是keyof DomType,而textElement只接受keyof TextType的键,直接赋值会触发类型校验错误,必须通过运行时的属性列表或类型守卫来做类型收窄。
内容的提问来源于stack exchange,提问作者Lex
相关产品推荐
相关产品推荐

