bounty还有3天到期。此问题的答案有资格获得+50声望奖励。msalla希望引起更多关注这个问题。
我在使用React组件的条件类型时遇到了TypeScript错误。
当尝试基于类型prop呈现不同类型的组件并为每种类型提供相应的prop时,就会出现问题。
type PairingCardProps = {
p: string;
};
type SampleCardProps = {
s: string;
};
export const GRID_CARD_COMPONENTS = {
pairing: ({ p }: PairingCardProps) => <div>Pairing Card</div>,
sample: ({ s }: SampleCardProps) => <div>Sample Card</div>,
};
type TypefaceGridCardProps =
| ({ type: "sample" } & SampleCardProps)
| ({ type: "pairing" } & PairingCardProps);
const TypefaceGridCard = ({ type, ...props }: TypefaceGridCardProps) => {
const Card = GRID_CARD_COMPONENTS[type as keyof typeof GRID_CARD_COMPONENTS];
if (!Card) return null;
return <Card {...props} />;
};
我遇到的错误如下:Type PairingCardProps is missing the following properties from type 'SampleCardProps': s
解决方案
我通过类型转换来解决这个问题,但发现上面的对象Map解决方案更好。
type TypefaceGridCardProps =
| ({
type: "pairing";
} & PairingCardProps)
| ({
type: "sample";
} & SampleCardProps);
const TypefaceGridCard = ({ type, ...props }: TypefaceGridCardProps) => {
switch (type) {
case "sample":
return <SampleCard {...(props as SampleCardProps)} />;
case "pairing":
return <PairingCard {...(props as PairingCardProps)} />;
default:
throw new Error(`Unknown type: ${type}`);
}
};
2条答案
按热度按时间ds97pgxw1#
编译器无法处理ms/TS#30581中描述的“相关联合类型”,但是,ms/TS#47109中描述了一个建议的重构,它考虑转移到泛型。首先,我们需要一些Map类型来保存每个组件的props:
现在,让我们使用mapped type重新定义
GRID_CARD_COMPONENTS
,并使用TypeMap
作为类型的源:让我们也定义
GRID_CARD_COMPONENTS
的类型,这是我们以后需要的:我们还应该为
TypefaceGridCard
参数创建一个Map类型,它将接受一个选项泛型参数K
,该参数扩展了TypeMap
的键,默认为keyof TypeMap
。此类型将返回给定K
的props或所有可能props的并集:让我们将我们的类型应用到
TypefaceGridCard
:奇怪的是,当我们尝试以JSX格式调用组件时,我们会得到一个错误。我不确定确切的原因,但我认为它必须对React的内部泛型类型做一些事情,这些类型无法正确处理此类情况。
解决方法是手动键入
Card
为FC<TypeMap[K]>
,并为props定义另一个类型为ComponentProps<typeof Card>
的变量,其值为props
:或者,你可以使用
as
Assert来代替创建另一个变量,但我不推荐这样做,因为它的类型安全性较差:Link to StackBlitz
i1icjdpr2#
我认为这是因为typescript编译器无法在
TypefaceGridCard
组件中推断出Card
组件。我也面临这类问题。所以这可以解为: