typescript - Zaštićeni tip, još uvijek nije dodjeljiv


Moj izlazni tip ovisi o ulaznom tipu. Štitim ulaz s prilagođenim čuvarom, ali još uvijek nije moguće dodijeliti ga deklariranom izlazu:

type InputType<Sub extends SubType> = { a: Sub, b: string }
type SubType = Sub1 | Sub2
type Sub1 = { a: string }
type Sub2 = { a: string, b: string }
type OutputType<Sub extends SubType> =
  Sub extends Sub2 ?
    { c: string, d: string } :
    { c: string }

function handle<Sub extends SubType>(mainType: InputType<Sub>): OutputType<Sub> {
  if (hasSub2(mainType)) {
    return {c: '', d: ''};
  } else {
    return {c: ''};
  }
}

function hasSub2(a: InputType<SubType>): a is InputType<Sub2> {
  return 'b' in a.a;
}

Evo igrališta

Odgovor #1

Trenutno ograničenje dizajna TS-a je da izrazi povratne vrijednosti funkcije moraju biti dodjeljivi eksplicitnoj nedefiniranoj anotaciji tipa povratne vrijednosti uvjetnog tipa, sužavanje s kontrolnim tokom ne pomaže (problem).

{c: '', d: ''} i {c: ''} u handle se ne mogu dodijeliti neriješenom uvjetnom povratnom tipu OutputType<Sub>. Možete učiniti sljedeće:

  1. pretvori sve izraze povratka u OutputType<Sub> (primjer)
  2. napravite zasebnu funkcijsku preopterećenje (primjer)

Provedba alternative 2

function handle<Sub extends SubType>(mainType: InputType<Sub>): OutputType<Sub>
function handle(mainType: InputType<SubType>): OutputType<SubType> {
  if ('b' in mainType.a) {
    return { c: '', d: '' };
  } else {
    return { c: '' };
  }
}

const sub1Res = handle({ a: { a: "aa" }, b: "b" }) // {c: string; }
const sub2Res = handle({ a: { a: "aa", b: "ab" }, b: "b" }) // { c: string; d: string; }

Na taj način, pozivatelj funkcije dobiva ispravan tip povratne vrijednosti, a također se sada tijelo funkcije (pozvani ili implementacijska strana) može kompajlirati.