type ItemMap = {
write: string[];
see: string[];
find: DataLibraryType[];
read: UploadFile[];
};
interface SearchListProps<K extends WaysType> {
currentWay: K;
list: ItemMap[K];
onClick: (val: ItemMap[K][number]) => void;
onRemove?: () => void;
}
type WaysType = 'write' | 'read' | 'see' | 'find'
我希望列表能够根据 currentWay 的值推断出不同的类型
但是错误
参数“index”隐式具有“any”类型,但可以从使用中推断出更好的类型。 ts(7044)
并且当 currentWay = 'read' 时,列表类型错误
错误消息:类型“string | ”上不存在属性“name”数据库类型 | UploadFile”属性“name”在类型“string”上不存在。
const SearchList = <K extends WaysType>(props: SearchListProps<K>) => {
const { currentWay, list, onClick, onRemove } = props
switch (currentWay) {
case 'write':
case 'see':
case 'find':
return <div>
{
list.map((r, index) => {
const itemName = currentWay === 'find' ? r?.name : r
return <div key={index}>{itemName}</div>
})
}
</div>
case 'read':
const currentFile = list?.[0]
// Attribute “name” does not exist on type “string | DataLibraryType | UploadFile<any>” Attribute “name” does not exist on type “string”.
const fileType = getFileExtension(currentFile?.name) || 'file'
if (!currentFile) {
return <></>
}
return <div>{currentFile?.desc}</div>
default:
return <></>
}
}
我希望列表能够根据 currentWay 的值推断出不同的类型
switch (currentWay) {
case 'write':
case 'see':
case 'find':
return <div>
{
list.map((r, index) => {
const itemName = currentWay === 'find' ? r?.name : r
return <div key={index}>{itemName}</div>
})
}
</div>
case 'read':
// list type is UploadFile[] no error
return <div>... </div>
这里的问题是打字稿无法自行缩小 K 参数的范围。如果你想知道为什么,请参阅缩小指南,实际上相当值得一读。
所以你必须帮助 typescript 缩小范围。
首先,请在这里阅读受歧视工会
这个联合背后的想法是,如果你有一个文字类型字段,比如你的 WaysType,你可以使用联合来定义更好的类型,而不是通用的 K 类型。
type WaysType = 'write' | 'read' | 'see' | 'find';
interface BaseProps {
onRemove?: () => void;
}
interface WriteOrSeeProps extends BaseProps {
currentWay: 'write' | 'see';
list: string[];
onClick: (val: string) => void;
}
interface FindProps extends BaseProps {
currentWay: 'find';
list: DataLibraryType[];
onClick: (val: DataLibraryType) => void;
}
interface ReadProps extends BaseProps {
currentWay: 'read';
list: UploadFile[];
onClick: (val: UploadFile) => void;
}
type SearchListProps = WriteOrSeeProps | FindProps | ReadProps;
这里是打字稿游乐场的链接,以说明工会如何不抛出任何错误游乐场