javascript - Typescript-egenskap tillåts endast om en annan egenskap finns
Säg att jag har en funktion där jag bara vill tillåta en egenskap om en annan egenskap är närvarande.
Jag försökte göra det så här, men det ger tillbaka ett fel Egenskapen 'c' finns inte på typen 'A'.
type A = {
a?: string;
} & ({ b: string; c?: string } | { b?: string });
const sad = (props: A) => {
const { a, b } = props;
const { c } = props; // Property 'c' does not exist on type 'A'.
return { a, b };
};
Några lösningar på detta?
Svar #1
Det enda sättet jag känner till är Användardefinierad Typvakt och jag gillar att kombinera det med Unionstyper
interface CommonProps {
a?: string
b?: string
}
interface SimpleProps extends CommonProps {
kind: "simple"
}
interface ComplexProps extends CommonProps {
kind: "complex"
c?: string
}
type Props = SimpleProps | ComplexProps
function isComplex(arg: Props): arg is ComplexProps {
return arg && arg.kind === 'complex'
}
const sad = (props: Props): any => {
if (isComplex(props)) {
const {a, b, c} = props
// do something
// return something
}
const { a, b } = props
// do something
// return something
}
Kort sagt, jag skapar ett gränssnitt för varje möjlig kombination av egenskaper. Sedan förenar jag dem under Props-typerna, och i min funktion använder jag user defined guards för att få tillgång till egenskaperna.
Svar #2
Unionstyper behåller bara de egenskaper som är gemensamma för de två typerna. I följande union har den resulterande typen bara en egenskap: b : string | undefined
{ b: string; c?: string } | { b?: string }
Följande kod kommer att uppnå det du ursprungligen förväntade dig, tror jag:
type A = {
a?: string;
} & ({ b: string; c?: string; } | { b?: undefined; c?: undefined; });
const sad = (props: A) => {
const { a, b } = props;
if (b) {
const { c } = props;
return { a, b, c };
}
return { a, b };
};
Utanför villkoret kan du inte använda c, men inom det har typen av props begränsats. Nu när b inte kan vara undefined är kompilatorn medveten om c.
