TypeScript中如何向对象内的类型化数组推送元素?解决类型不兼容错误
解决TypeScript联合类型参数不匹配错误
错误信息
Argument of type 'Dogs | Cats | Fishs' is not assignable to parameter of type 'Dogs & Cats & Fishs'.
Type 'Dogs' is not assignable to type 'Dogs & Cats & Fishs'.
Property 'owner' is missing in type 'Dogs' but required in type 'Cats'.
原代码
interface Dogs { height: number, age: number, race: string, available: boolean, } interface Cats { height: number, age: number, owner: string } interface Fishs { weight: number, age: number, water: "sweet" | "salty" } interface Foo { animals: { dogs?: Dogs[], cats?: Cats[], fishs?: Fishs[] } } type FooKeys = keyof Foo["animals"] type FooState = Required<Foo>["animals"] type FooStateTypes = Required<FooState>[keyof FooState][0] const addAnimal = (fooState: FooState, animal: FooStateTypes, fooKey: keyof FooState) => { const fooStateAnimal = fooState[fooKey] if(fooStateAnimal) { fooStateAnimal.push(animal) } else { fooState[fooKey] = [animal] } }
问题原因
当前函数中,fooKey和animal的类型是独立的联合类型,TypeScript无法确认传入的animal类型与fooKey对应的数组元素类型一致。它会假设fooState[fooKey]可能是Dogs[]、Cats[]或Fishs[]中的任意一种,因此要求animal必须同时满足三种类型的交集(Dogs & Cats & Fishs)才能安全推入所有可能的数组,这显然不符合实际需求。
解决方案
使用泛型绑定fooKey和animal的类型,让TypeScript明确两者的对应关系:
interface Dogs { height: number, age: number, race: string, available: boolean, } interface Cats { height: number, age: number, owner: string } interface Fishs { weight: number, age: number, water: "sweet" | "salty" } interface Foo { animals: { dogs?: Dogs[], cats?: Cats[], fishs?: Fishs[] } } type FooKeys = keyof Foo["animals"] type FooState = Required<Foo>["animals"] type FooStateTypes = Required<FooState>[keyof FooState][0] const addAnimal = <K extends keyof FooState>( fooState: FooState, animal: Required<FooState>[K][0], fooKey: K ) => { const fooStateAnimal = fooState[fooKey]; if (fooStateAnimal) { fooStateAnimal.push(animal); } else { // 类型断言告知TypeScript当前赋值的数组类型与fooKey对应 fooState[fooKey] = [animal] as Required<FooState>[K]; } }
关键说明
- 泛型
K约束为keyof FooState,限定fooKey只能是"dogs"、"cats"或"fishs"中的一个 animal的类型定义为Required<FooState>[K][0],直接关联到fooKey对应的数组元素类型,确保两者类型匹配- 赋值时的类型断言解决了可选属性赋值时的类型窄化问题
内容的提问来源于stack exchange,提问作者four-eyes
相关产品推荐
相关产品推荐

