簡體   English   中英

Typescript:如何使返回類型只接受接口的子類型

[英]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索引,它會計算返回類型。 如果Tmap的鍵,則返回typeof map[T]對應的組件類型。 如果不是,我們返回typeof Placeholder


操場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM