Я пытаюсь заставить работать что-то вроде следующего, однако typescript выводит ошибки при попытке доступа к свойству o.foo
:
type Base = { s: string };
type Extra = { foo: string; };
type Other = { bar: string; };
type T = Base & (Extra | Other);
function f(o: T): string {
if (typeof o.foo === 'string') {
return o.s + o.foo;
}
return o.s + o.bar;
}
Ошибка
Property 'foo' does not exist on type 'T'.
Property 'foo' does not exist on type 'Base & Other'.
Похоже, машинописный текст не может правильно вывести, что если o
имеет свойство foo
, то есть строку, то тип o
должен быть в Base & Extra
ветви объединения.
Есть ли способ заставить его понять это?
Вы не можете получить доступ к членам союза, если они не являются общими. Вместо этого вы можете использовать in
typeguard:
type Base = { s: string };
type Extra = { foo: string; };
type Other = { bar: string; };
type T = Base & (Extra | Other);
function f(o: T): string {
if ('foo' in o) {
return o.s + o.foo;
}
return o.s + o.bar;
}
Это возможно в потоке (см. «Непересекающиеся союзы» в flow.org/en/docs/types/unions/#toc-unions-refinements), но я не уверен, что это работает в машинописном тексте.