[英]Typescript property does not exist on extended type
我有一個 react 組件,它可以使用to
(react-router-dom prop) 或href
屬性,具體取決於我要重定向用戶的位置; 無論是在應用程序內還是外部 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>
)}
);
}
因為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 (<> ... </>);
}
另一種選擇是使用“標記”聯合來解決對類型保護 function 的需求。 這些 go 有一些不同的名稱,具體取決於您與誰交談。 您可以找到這些的其他名稱是“歧視性工會”和“不相交工會”來命名一對。
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 (<> ... </>);
}
因此,如果您檢查LinkType['type']
您將看到'router' | 'href'
'router' | 'href'
和 TypeScript 可以自動縮小類型,如果您對 LinkType 的此類型屬性執行 if 語句。
你可以這樣做:
type LinkType = RouterLink & HrefLink;
這樣你就不必用代碼縮小聯合
編輯 1。
亞歷克斯·D 。 提出了這種方法可能產生的副作用。 基本上,如果不滿足所有屬性( href 、 label 、 to ),您將無法定義 LinkType object ,這可以通過使用 Partials 或簡單地將href
和to
聲明為可選來解決,例如
interface HrefLink extends LinkBase {
href?: string;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.