Как задать нужный тип в TS
class El { };
interface Impure {
__value__:any
}
type Box = El | Impure;
function walk(childs:Box[]) {
var child: Box;
for (var i = 0; i < childs.length; i++) {
child = childs[i];
if (child.__value__) { // Error ( Property '__value__' does not exist on type Box)
// Property '__value__' does not exist on type El
}
}
}
тип Box определяется как El или Impure, да в El свойство 'value' Нету, но поэтому и ставится условие if, но TS пишит error, не смотря на if. Интересно как решаются подобные вещи
Ответы (1 шт):
Автор решения: qwabra
→ Ссылка
если не путаю, врсии так с 2.9 появились вот такие функции
type Some = any;
const isSome = (q: any): q is Some => true
- User-Defined Type Guards - https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards
в вашем же примере оно будет так
class El { qqp: any }
interface Impure { __value__: any }
type Box = El | Impure;
const isImpure = (q: any): q is Impure => '__value__' in q
const isEl = (q: any): q is El => q instanceof El
function walk(childs: Box[]) {
var child: Box;
for (var i = 0; i < childs.length; i++) {
child = childs[i];
test1: {
if (isImpure(child)) {
child.__value__
} else {
child.qqp
}
// child.qqp // err
}
test2: {
if (isEl(child)) {
child.qqp
} else {
child.__value__
}
// child.qqp // err
}
test3: {
if (!isEl(child)) break test3;
child.qqp // is OK
}
}
в прочем сегодня и такие конструкции TS понимает
class El { qqp: any }
interface Impure { __value__: any }
type Box = El | Impure;
function walk(childs: Box[]) {
var child: Box;
for (var i = 0; i < childs.length; i++) {
child = childs[i];
test4: {
if ('__value__' in child) {
child.__value__
}
}
}
}
а раньше писали так (child as Impure).__value__
class El { qqp: any }
interface Impure { __value__: any }
type Box = El | Impure;
function walk(childs: Box[]) {
var child: Box;
for (var i = 0; i < childs.length; i++) {
child = childs[i];
test5: {
if ('__value__' in child) {
(child as Impure).__value__
}
}
}
}