Laz*_*zyk 8 typescript reactjs
我有一个 React 组件,它要么采用to
(react-router-dom prop) 要么采用href
prop,具体取决于我想将用户重定向到哪里;无论是在应用程序内还是外部 URL。Typescript 抱怨我的类型
类型“LinkType”上不存在属性“to”。
类型“LinkType”上不存在属性“href”。
这就是我定义我的类型的方式
import React from 'react';
import { Link } from 'react-router-dom';
interface LinkBase {
label: string;
icon?: JSX.Element;
}
interface RouterLink extends LinkBase {
to: string;
}
interface HrefLink extends LinkBase {
href: string;
}
type LinkType = RouterLink | HrefLink;
export function NavLink(props: LinkType) {
const { to, label, icon, href } = props; // TS complains about those to and href
return(
{to ? (
<Link to={to}>{label}</Link>
) : (
<a href={href}>{label}</a>
)}
);
}
Run Code Online (Sandbox Code Playgroud)
因为LinkType
是一个并集,HrefLink
并且RouterLink
都可以分配给LinkType
。HrefLink
上面没有“to”,RouterLink 上也没有“href”。因此,TypeScript 无法保证联合中存在这些属性中的任何一个。您可以使用类型保护来完成您想要做的事情,同时也满足 TypeScript。
import React from 'react';
import { Link } from 'react-router-dom';
interface LinkBase {
label: string;
icon?: JSX.Element;
}
interface RouterLink extends LinkBase {
to: string;
}
interface HrefLink extends LinkBase {
href: string;
}
type LinkType = RouterLink | HrefLink;
function isRouterLink(v: unknown): v is RouterLink {
return v && Object.prototype.hasOwnProperty.call(v, 'to');
}
function isHrefLink(v: unknown): v is HrefLink {
return v && Object.prototype.hasOwnProperty.call(v, 'href');
}
export function NavLink(props: LinkType) {
const { label, icon } = props;
if (isRouterLink(props)) {
const { to } = props; // typechecks now
return (<> ... </>)
}
if (isHrefLink(props)) {
const { href } = props;
return (<> ... </>);
}
return (<> ... </>);
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用“标记”联合来解决类型保护函数的需要。根据与您交谈的对象不同,这些名称有不同的名称。您还可以找到这些的其他名称,例如“歧视联盟”和“不相交联盟”。
interface LinkBase {
label: string;
icon?: JSX.Element;
}
interface RouterLink extends LinkBase {
type: 'router';
to: string;
}
interface HrefLink extends LinkBase {
type: 'href';
href: string;
}
type LinkType = RouterLink | HrefLink;
export function NavLink(props: LinkType) {
const { label, icon } = props;
if (props.type === 'router') {
const { to } = props; // typechecks now
return (<> ... </>);
}
if (props.type === 'href') {
const { href } = props;
return (<> ... </>);
}
return (<> ... </>);
}
Run Code Online (Sandbox Code Playgroud)
因此,如果您检查 的类型,LinkType['type']
您将看到'router' | 'href'
,并且如果您对 LinkType 的此类型属性执行 if 语句,TypeScript 可以自动为您缩小类型范围。
归档时间: |
|
查看次数: |
4026 次 |
最近记录: |