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
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;
}
1
Aleksey L.
20 grudzień 2019, 10:35
hasOwnProperty
nie jest strażnikiem typu: typescriptlang.org/docs/handbook/…