Istnieje interfejs, który może być jednym z wielu interfejsów

interface a {x:string}
interface b {y:string}
interface c {z:string}
type all = a | b | c

Później obiekt spełnia wymagania all, ponieważ jest typu c

Powołanie

    if (obj.hasOwnProperty('z')) {
      return obj.z
    }

Nie można się skompilować, ponieważ:

Właściwość „z” nie istnieje w przypadku typu „a”.

Jak to rozwiązujesz?

0
Marcus 20 grudzień 2019, 01:43
hasOwnProperty nie jest strażnikiem typu: typescriptlang.org/docs/handbook/…
 – 
jonrsharpe
20 grudzień 2019, 01:57

2 odpowiedzi

obj.hasOwnProperty('z') nie gwarantuje samo w sobie, że obj spełnia wymagania interfejsu c. Załóżmy, że obj ma być zadeklarowane jako

var obj = { x: "foo"; y: "bar"; z: true };

W tym przypadku obj spełnia a i b, ale nie c, ponieważ obj.z nie jest ciągiem.

Możesz jednak napisać własne typy strażników, aby obejść ten problem:

function isC(obj: all): obj is c {
  return obj.hasOwnProperty('z');
  // or return 'z' in obj;
}

...

if (isC(obj)) {
  return obj.z; // this is fine
}
0
p.s.w.g 20 grudzień 2019, 01:59

Jeśli w Twoim przypadku dopuszczalne jest zastąpienie hasOwnProperty przez in i nie chcesz definiować osłon typu niestandardowego - in wykona to zadanie:

interface a { x: string }
interface b { y: string }
interface c { z: string }
type all = a | b | c;

function foo(obj: all) {
  if ('z' in obj) {
    return obj.z; // obj type is narrowed to c
  }
  return undefined;
}

Plac zabaw

1
Aleksey L. 20 grudzień 2019, 10:35