typescript - ukloni null ili undefined iz svojstava tipa
Treba mi deklarirati tip koji uklanja undefined iz tipova svojih svojstava.
Pretpostavimo da imamo:
type Type1{
prop?: number;
}
type Type2{
prop: number | undefined;
}
type Type3{
prop: number;
}
Trebam definirati generički tip nazvan NoUndefinedField<T> tako da NoUndefinedField<Type1> daje isti tip kao Type3 i isti tip kao NoUndefinedField<Type2>.
Pokušao sam ovo
type NoUndefinedField<T> = { [P in keyof T]: Exclude<T[P], null | undefined> };
Ali to radi samo za Type2.
Odgovor #1
Upotrijebite ugrađeni tip NonNullable:
type NonNullable<T> = Exclude<T, null | undefined>; // Remove null and undefined from T
Pogledajte TypeScript: Dokumentacija - Pomoćne tipove
Odgovor #2
Zahvaljujući @artem, rješenje je:
type NoUndefinedField<T> = { [P in keyof T]-?: NoUndefinedField<NonNullable<T[P]>> };
Primijetite -? sintaksu u [P in keyof T]-? koja uklanja opcionalnost
Odgovor #3
Odgovor @DShook je netočan (ili bolje rečeno nepotpun) jer OP traži uklanjanje null i undefined iz svojstava tipova, a ne iz samog tipa (značajna razlika).
Iako je @Fartabov odgovor točan, dodati ću mu, budući da sada postoji ugrađeni Required tip, a rješenje se može prepisati kao:
type RequiredProperty<T> = { [P in keyof T]: Required<NonNullable<T[P]>>; };
Ovo će preslikati svojstva tipova (ne sam tip) i osigurati da nijedno od njih nije: null ili undefined.
Primjer razlike između uklanjanja null i undefined iz tipa, naspram njihovog uklanjanja iz svojstava tipa (koristeći gore navedeni RequiredProperty tip):
type Props = {
prop?: number | null;
};
type RequiredType = NonNullable<Props>; // { prop?: number | null }
type RequiredProps = RequiredProperty<Props>; // { prop: Required<number> } = { prop: number }
Odgovor #4
Danas možete koristiti Required da biste točno napravili ono što vam je potrebno:
Required<Type1>
To će rezultirati time da će sva polja postati obavezna. Više detalja možete pronaći ovdje
Odgovor #5
Nešto u odgovorima @Fartab i @tim.stasse mi kvari svojstvo tipa Date:
// both:
type NoUndefinedField<T> = {
[P in keyof T]-?: NoUndefinedField<NonNullable<T[P]>>;
};
type NoUndefinedField<T> = {
[P in keyof T]-?: NoUndefinedField<Exclude<T[P], null | undefined>>;
};
// throw:
Property '[Symbol.toPrimitive]' is missing in type 'NoUndefinedField<Date>' but required in type 'Date'.ts(2345)
// and
type NoUndefinedField<T> = { [P in keyof T]: Required<NonNullable<T[P]>> };
// throws:
Property '[Symbol.toPrimitive]' is missing in type 'Required<Date>' but required in type 'Date'.ts(2345)
Imam uspjeha s ovim rješenjem bez rekurzije:
type NoUndefinedField<T> = {
[P in keyof T]-?: Exclude<T[P], null | undefined>;
};
