如何在 TypeScript 中输入泛型函数?

问题描述 投票:0回答:1

给定以下类型和组件:

interface Widget { type: string; }
interface TextField extends Widget { type: 'TextField'; textValue: string; }
interface Checkbox extends Widget { type: 'Checkbox'; booleanValue: boolean; }

type Props<W extends Widget> = { widget: W; }
type WidgetComponent<W extends Widget> = (props: Props<W>) => React.ReactNode;

const TextfieldComponent: WidgetComponent<TextField> = ({ widget }) => { return <input type="text" /> };
const CheckboxComponent: WidgetComponent<Checkbox> = ({ widget }) => { return <input type="checkbox" />};

以及以下谓词:

const isTextfield = (widget: Widget): widget is TextField => widget.type === 'TextField';
const isCheckbox = (widget: Widget): widget is Checkbox => widget.type === 'Checkbox';

如何正确输入给定的函数?

const factory = <W extends Widget>(widget: W): WidgetComponent<W> | null => {
    if (isTextfield(widget)) {
        return TextfieldComponent;
    } else if (isCheckbox(widget)) {
        return CheckboxComponent;
    }
    return null;
}

TypeScript 不喜欢这样,它告诉我:

Type 'WidgetComponent<TextField>' is not assignable to type 'WidgetComponent<W>'.
  Type 'W' is not assignable to type 'TextField'.
    Property 'textValue' is missing in type 'Widget' but required in type 'TextField'.(2322)

我理解为什么 TypeScript 给我这个错误,但我不知道应该使用哪种机制来为 TypeScript 提供正确的类型约束。

您可以在 TypeScript 游乐场上看到它的实际效果

reactjs typescript type-constraints
1个回答
0
投票

您应该使用条件类型将小部件类型映射到其相应的组件类型。

const factory = <W extends Widget>(widget: W): WidgetComponent<W> | null => {
    if (isTextfield(widget)) {
        return TextfieldComponent as WidgetComponent<W>;
    } else if (isCheckbox(widget)) {
        return CheckboxComponent as WidgetComponent<W>;
    }
    return null;
};
© www.soinside.com 2019 - 2024. All rights reserved.