在Typescript 2.1中,尝试以下操作时:
// address.tsx
...
interface Address {
street: string;
country: string;
}
interface CanadianAddress extends Address {
postalCode: string;
}
interface AmericanAddress extends Address {
zipCode: string;
}
type Properties = AmericanAddress | CanadianAddress'
function isAmerican(address: Properties) address is AmericanAddress {
return 'zipCode' in address;
}
export class Address extends React.Component<Properties, void> {
public render() {
let isAmerican = isAmerican(this.props.address);
...
}
}
// map.tsx
...
let rootDiv = document.createElement('root')l
ReactDOM.render(<Address postalCode='T1B 0L3' />, rootDiv);
在编译时发生跟随错误:
错误TS2600:JSX元素属性类型'({children?:ReactNode;}&amp; AmericanAddress)| ({children?:ReactNode;}&amp; CanadianAddress'可能不是联合类型。
我想知道为什么不支持这个,以及如何在不指定过于复杂的属性的情况下完成此操作?
答案 0 :(得分:0)
我不确定为什么它不可能,我能找到的只有@RyanCavanaugh:
我们并没有真正正确地支持JSX属性类型 联合类型
在问题中:Allow JSX element attributes type to be an intersection。
解决这个问题的方法是有两个不同的组件,它们是Address
的子类:
interface AddressProperties {
street: string;
country: string;
}
interface CanadianAddressProperties extends AddressProperties {
postalCode: string;
}
interface AmericanAddressProperties extends AddressProperties {
zipCode: string;
}
abstract class Address<P extends AddressProperties> extends React.Component<P, void> {
public render() {
return (
<div className={ this.getClassName() + " address"}>
<div><span>Street:</span><span>{ this.props.street }</span></div>
<div><span>Country:</span><span>{ this.props.country }</span></div>
{ }
</div>
);
}
protected abstract getClassName(): string;
protected abstract getCountryElements(): JSX.Element | JSX.Element[];
}
class CanadianAddress extends Address<CanadianAddressProperties> {
protected getClassName(): string {
return "canadian";
}
protected getCountryElements(): JSX.Element {
return <div><span>Postal Code:</span><span>{ this.props.postalCode }</span></div>;
}
}
class AmericanAddress extends Address<AmericanAddressProperties> {
protected getClassName(): string {
return "american";
}
protected getCountryElements(): JSX.Element {
return <div><span>Zip Code:</span><span>{ this.props.zipCode }</span></div>;
}
}
如果两者之间的唯一变化是zipCode
/ postalCode
,那么它可能是一种过度杀伤,但如果存在更多差异,则将两者分成不同的组件是有意义的。
否则,您需要在postalCode
中将zipCode
和AddressProperties
作为可选项。