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>;
};

Povezani članci