TypeScript联合类型引发的类型混淆问题求助
TypeScript联合类型引发的类型混淆问题求助
你好呀,这个问题的核心在于你的GenericSelect组件没有把values的类型和onChange的参数类型做关联,导致TypeScript没办法根据你传入的具体数组自动推断出onChange参数的准确类型——哪怕你用了类型收窄,组件本身的联合类型定义还是会让TS“犯迷糊”。
解决这个问题的关键是用泛型来绑定这两个属性的类型,让TS明确知道:当你传入的是Book[],onChange的参数就一定是Book;如果传入的是Movie[],参数就一定是Movie。
来看看修改后的完整代码:
首先保留你的基础类型定义,然后改造组件的类型和实现:
export type Book = { id: string; title: string; author: string; }; export type Movie = { id: string; title: string; releaseDate: string; }; // 改成泛型Props,让values和onChange的类型绑定 type GenericSelectProps<T extends Book | Movie> = { values: T[]; onChange: (value: T) => void; }; // 泛型组件实现 export const GenericSelect = <T extends Book | Movie>({ values, onChange }: GenericSelectProps<T>) => { // 给事件参数加上明确类型,避免any const onSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => { const val = values.find((value) => value.id === e.target.value); if (val) onChange(val); }; return ( <select onChange={onSelectChange}> {values.map((value) => ( <option key={value.id} value={value.id}> {value.title} </option> ))} </select> ); };
现在再使用组件时,TypeScript会自动精准推断类型:
const books: Book[] = [ { id: "1", title: "Good omens", author: "Terry Pratchett & Neil Gaiman" }, { id: "2", title: "The Truth", author: "Terry Pratchett" } ]; // 这里value会被自动推断为Book类型,直接访问author毫无问题 <GenericSelect onChange={(value) => console.log(value.author)} values={books} />
这样不仅不需要再写类型收窄的冗余代码,TS也不会再抛出类型错误啦~
备注:内容来源于stack exchange,提问作者mir 433




