TypeScript中对象赋值时如何设置键值类型并解决赋值错误?
TypeScript相关问题解答
1. 对象赋值时如何设置键类型与值类型?
常见的约束方式有三种:
- 固定结构对象:用
interface或type别名直接定义每个键的名称和对应值类型,比如你代码里的Student接口,赋值时必须严格匹配定义的类型结构。 - 动态键对象:通过索引签名统一约束键和值的类型,示例:
// 所有键为string类型,值为number类型的对象 type NumberMap = { [key: string]: number }; const scores: NumberMap = { math: 90, english: 85 }; - 类型安全的动态赋值:结合
keyof和泛型,确保赋值时键与值的类型严格对应,示例:function setProp<T, K extends keyof T>(obj: T, key: K, value: T[K]) { obj[key] = value; } // 调用时编译器会自动检查键和值的类型匹配度 setProp(alice, "name", "Alice Updated");
2. 修复遍历赋值的编译错误
错误原因
遍历(keyof Student)[]类型数组时,TypeScript无法推断当前键c对应的具体值类型,仅能知道alice[c]和bob[c]的类型是string | number,但无法保证两者类型完全匹配(比如可能把字符串赋值给数字类型属性),因此编译器将目标类型推断为never,抛出类型不兼容错误。
解决方案
方案1:类型断言(简单直接)
因为你明确知道c是Student的合法键,bob[c]的类型必然和alice[c]一致,可通过类型断言告知编译器:
interface Student { id: number name: string age: number } let alice: Student = { name: "alice", age: 19, id: 1 } const bob: Student = { name: "Bob", age: 19, id: 2 } const keys: (keyof Student)[] = ["age", "name"] for (let c of keys) { alice[c] = bob[c] as typeof alice[c]; }
方案2:泛型函数封装(更安全)
用泛型让TypeScript推断每个键对应的具体类型,从根源消除类型歧义:
interface Student { id: number name: string age: number } let alice: Student = { name: "alice", age: 19, id: 1 } const bob: Student = { name: "Bob", age: 19, id: 2 } const keys: (keyof Student)[] = ["age", "name"]; function copyProperty<T, K extends keyof T>(target: T, source: T, key: K) { target[key] = source[key]; } for (let c of keys) { copyProperty(alice, bob, c); }
方案3:Object.assign(更简洁)
如果只是复制指定属性,用Object.assign结合属性提取更高效:
interface Student { id: number name: string age: number } let alice: Student = { name: "alice", age: 19, id: 1 } const bob: Student = { name: "Bob", age: 19, id: 2 } const keys: (keyof Student)[] = ["age", "name"]; const propsToCopy = {} as Pick<Student, typeof keys[number]>; for (let c of keys) { propsToCopy[c] = bob[c]; } Object.assign(alice, propsToCopy);
内容的提问来源于stack exchange,提问作者ramwin
相关产品推荐
相关产品推荐

