javascript - Hvordan implementere et grensesnitt med betingede typer i TypeScript
I et personlig prosjekt står jeg overfor et problem med TypeScript betingede typer. Jeg har grunnleggende forståelse av betingede typer fra TypeScript-dokumentasjonen. Jeg ville forventet at oppsettet nedenfor skulle fungere, men det gir en typefeil.
I utgangspunktet prøver jeg å definere et grensesnitt for en tre-node som lastes fra disken. Dette betyr at noen av nodene kanskje ikke lastes riktig på grunn av manglende filer osv. Så enhver node-implementering inneholder enten Content eller Error.
interface Content {
data: number;
}
interface Error {
code: string;
}
export interface TreeNode<T extends Content | Error> {
getValue(): T extends Content ? number : string;
}
class ValueNode<ValueType extends Content> implements TreeNode<ValueType> {
private readonly value: number;
public constructor(value: number) {
this.value = value;
}
public getValue(): number {
return this.value;
}
}
Jeg ville forventet at implementeringen av getValue-metoden ville være tillatt å returnere string siden grensesnittet er implementert med type som utvider Content. Men jeg får denne typefeilen i stedet:
Egenskapen
getValuei typenValueNode<ValueType>kan ikke tilordnes til samme egenskap i basistypenTreeNode<ValueType>.
Type
() => numberkan ikke tildeles til type() => ValueType extends Content ? number : string.
- Type
numberkan ikke tildeles typeValueType extends Content ? number : string- Type
() => numberkan ikke tilordnes til type() => ValueType extends Content ? number : string.- Type
numberkan ikke tilordnes til typeValueType extends Content ? number : string
Klart, jeg gjør det på feil måte. Hva ville være den riktige måten å oppnå målet mitt på?
Svar #1
Som @Dai påpekte, er det bedre å ikke overskygge den innebygde
Error-typen (slik at du kan bruke den i modulen din).
Her er to alternativer:
TS-lekeplasslenke
interface ContentValue {
data: number;
}
interface ErrorValue {
code: string;
}
export interface ValueGetter<T> {
getValue(): T;
}
class ValueNode<T extends ContentValue> implements ValueGetter<ContentValue['data']> {
public constructor(private readonly value: T) {}
public getValue(): number {
return this.value.data;
}
}
// or
class SimpleValueNode<T extends ContentValue> {
public constructor(private readonly value: T) {}
public getValue(): number {
return this.value.data;
}
}
