歧视的联合可以根据其类型的类型允许一些属性 我正在与React和打字稿一起工作。 我创建了一个可以渲染SVG的组件,并且它的版本返回包裹在链接中的SVG。 这两个版本都有一些常见...

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

isLink

先前的示例工作

,如果我将href定义为可选的未定义属性,则是这样的:

const Mycomponent = <Logo label="payment" variant="paypal" href="http://paypal.com" /> 
// error because isLink is missing and we are using 'href'

const Mycomponent = <Logo isLink label="payment" variant="paypal" href="http://paypal.com" /> 
// correct because isLink is true and therefore we need and 'href'

如果在接口徽标中,则删除您不会遇到任何错误的“ HREF”属性(我希望它具有错误):

import React, { FC } from "react"; type ValidRel = "alternate" | "author" | "bookmark"; export type LinkProps = { rel?: ValidRel; href: string; target?: "_blank" | "_self" | "_parent" | "_top"; }; interface CommonProps { variant: "paypal" | "visa" | "mastercard"; className?: string; }; interface LogoBase extends CommonProps { label?: string; }; interface Logo extends LogoBase { isLink?: false; // if you remove the line below you have a Logo without "isLink" property // and a "href" property (which should be wrong combination) href?: undefined; }; interface InteractiveLogo extends LogoBase, LinkProps { isLink: true; label: string; }; export type Props = InteractiveLogo | Logo; const Logo: FC<Props> = ({ variant, label, className, ...unionProps }) => { if ("href" in unionProps) { return ( <a {...unionProps}> <p className={className} aria-label={label}>{variant} </p> </a> ); } return <p className={className} aria-label={label}>{variant} </p> }; const Mycomponent = <Logo label="payment" variant="paypal" href="http://paypal.com" />

如果我像字符串的结合而不是字符串键入“ HREF”,那么更奇怪的是,它可以正如我期望的那样恢复正常。当然,“ HREF”不能固定字符串,因为将是提供的任何URL:

interface Logo extends LogoBase {    
      isLink?: false;  
      //removed: href?: undefined;
    };

Playground

	
您正在推动类型系统来执行要做的组件要做的事情 - 最好将实现分开:

export type LinkProps = { rel?: ValidRel; href: "www.goole.es" | "www.hotmail.com"; // this union makes the types work OK again target?: "_blank" | "_self" | "_parent" | "_top"; };

const Logo: FC<Logo> = ({ variant, label, className }) => ( <p className={className} aria-label={label}> {variant}{" "} </p> );

Tsfiddle在这里 如果出于某种原因,您需要将代码组合为实施,则可以简单地做:

reactjs typescript
1个回答
0
投票

风格注意:很容易不要重复自己并删除所有内容,但是只需要始终需要始终相同的代码。
注意,在最高建议中感觉就像重复,但是重复的唯一行是方法的参数。
    

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.