[英]Typescript: How to make a type that is the keys of an interface but only the keys that are strings
[英]Typescript: how to make return type only accept subtype of interface
對不起標題,我真的不知道這個名字。
我正在編寫一個映射器 function,它接受一個類型並在 React 中返回一個組件,並且對如何為其編寫返回類型感到困惑。
基本上每個組件都接收 {data} 或IBlock
的子類型。
// simulate React
interface FunctionComponent<P = {}> {
(props: P): string;
}
type FC<P = {}> = FunctionComponent<P>;
// actual code
export enum BlockType {
'HEADER'='header',
'HEADING'='heading',
'GROUP'='group',
'CARD'='card',
'IMAGE'='image',
}
export interface IBlock {
type: BlockType;
id?: string;
elements?: IBlock[];
[key: string]: unknown;
}
export interface IHeader extends IBlock {
type: BlockType.HEADER;
title: string;
}
export interface IHeading extends IBlock {
type: BlockType.HEADING;
paragraph: string;
}
export interface IBlockComponentProps<T extends IBlock> {
data: T,
children?: string[]
}
const Placeholder: FC<IBlockComponentProps<IBlock>> = ({data}) => {
return data.type;
};
const Header: FC<IBlockComponentProps<IHeader>> = ({data}) => {
return data.title;
}
const Heading: FC<IBlockComponentProps<IHeading>> = ({data}) => {
return data.paragraph;
}
function typeToComp(type: BlockType): FC<IBlockComponentProps<any>> {
const map = {
[BlockType.HEADER as string]: Header,
[BlockType.HEADING as string]: Heading
};
return map[type] ?? Placeholder;
};
我的問題是:這里應該放any
而不是放什么? 我想說的是:每個類型/接口都是IBlock
的子類型
function typeToComp(type: BlockType): FC<IBlockComponentProps<any>>
如果我將IBlock
放在那里,它會抱怨每個接受其子類型的組件,而我不能(或不想)將每個子類型放在那里。
請幫忙。 謝謝
擁有通用的超類型函數並不是真正的類型安全。 您的函數期望傳遞IBlock
的子類型。 將它們分配給類似於FC<IBlockComponentProps<IBlock>>
的東西將允許使用IBlock
類型的東西調用組件,即使它們期望IBlock
的子類型。
您應該考慮重寫 function,以便它返回給定類型T
的正確組件類型,而不僅僅是一些通用類型。
function typeToComp<T extends BlockType>(type: T) {
const map = {
[BlockType.HEADER]: Header,
[BlockType.HEADING]: Heading
};
return (map[type as keyof typeof map] ?? Placeholder) as (
typeof map & {
[K in Exclude<BlockType, keyof typeof map>]: typeof Placeholder
}
)[T]
};
我們可以構造一個可索引類型,如果由T
索引,它會計算返回類型。 如果T
是map
的鍵,則返回typeof map[T]
對應的組件類型。 如果不是,我們返回typeof Placeholder
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.