Typescript如何强制Record键名与内部name属性值保持一致?
解决方案
核心实现思路是通过泛型工具函数自动推导传入对象的键类型,同时完成键名与对应值name属性的一致性校验,无需提前汇总所有键名,完全适配大体量数据场景。
实现代码
interface Person<T extends string> { name: T title: string description: string } // 泛型验证函数,TS会自动根据传入的对象推导键类型,无需提前声明 function definePeople<T extends string>(people: { [K in T]: Person<K> }) { return people }
使用示例
正确用法
// 无需手动标注类型,TS自动完成校验与推导 const correctData = definePeople({ sarah: { name: 'sarah', title: 'Sarah', description: 'Hello', }, bob: { name: 'bob', title: 'Bob', description: 'Hi' } })
错误用法
const badData = definePeople({ adam: { name: 'john', // TS直接抛出错误:Type '"john"' is not assignable to type '"adam"' title: 'Adam', description: 'Wrong info' } })
动态新增数据适配
如果需要后续动态给对象添加属性,可以配套写一个新增工具函数,同样自动做一致性校验:
function addPerson<T extends string, P extends Record<string, Person<any>>>( people: P, key: T, person: Person<T> ): P & Record<T, Person<T>> { return { ...people, [key]: person } } // 动态添加示例 let people = definePeople({}) people = addPerson(people, 'lisa', { name: 'lisa', // 写错name会直接报错 title: 'Lisa', description: 'New user' })
原写法报错原因
你之前尝试的const people: People<keyof typeof people> = {}写法会报错,是因为TS解析类型标注时变量还未完成声明,无法推断typeof people的实际类型,通过工具函数的方式可以让TS从函数入参推导类型,完美绕开这个问题。
内容的提问来源于stack exchange,提问作者spirift
相关产品推荐
相关产品推荐

