#typescript #typescript-generics
#typescript #typescript-обобщения
Вопрос:
У меня есть следующий класс
class A {
id: number
propertyA: string
constructor(id: number) {
this.id = id
}
}
let a = new A(3)
console.log(SomeFunction(a))
// expected output = ['id', 'propertyA']
В принципе, когда я создавал экземпляр A, я не задавал значение для PropertyA. При SomeFunction(a)
вызове он должен возвращать все свойства, которые могут быть у класса A, включая propertyA
даже если оно не было задано.
Object.getPropertyNames(a)
возвращает только ['id']
Каким должен быть код someFunction?
Ответ №1:
Если вы не зададите значение для свойства, оно не будет существовать в объекте. Во время выполнения нет доступных метаданных, в которых говорилось бы «Это свойство объявлено, но ему никогда не назначалось».
Вам нужно будет выбрать значение по умолчанию для propertyA
и установить его (возможно, в инициализаторе объявления), если вы хотите убедиться, что каждый экземпляр A
обладает этим свойством.
Например, если вы не используете строгие проверки на нуль, вы могли бы сделать это:
class A {
id: number
propertyA: string = undefined
constructor(id: number) {
this.id = id
}
}
Это означает, что new A(42).propertyA
будет по-прежнему предоставлять значение undefined
(как это происходит с вашим существующим A
классом), но свойство будет фактически существовать, и поэтому SomeFunction
его можно будет найти.
Живая копия:
class A {
id /* : number*/
propertyA /*: string*/ = undefined
constructor(id/*: number*/) {
this.id = id
}
}
console.log(Object.getOwnPropertyNames(new A(42)));
Если вы используете строгие проверки на нуль, вам нужно будет инициализировать его в виде строки.
Комментарии:
1. Ах… Я так и подозревал. Спасибо за разъяснение
Ответ №2:
Пока значение свойства не задано, оно не будет существовать в экземпляре класса.
Здесь мы можем перечислять оба id
и propertyA
, но только тогда, когда они установлены:
function showProps(obj) {
return Object.keys(obj);
}
class A {
constructor(id, propA) {
this.id = id;
if (propA)
this.propertyA = 0;
}
}
const a = new A(3);
const b = new A(3, 1);
console.log(showProps(a));
console.log(showProps(b));
Комментарии:
1. «…как только он скомпилирован в JavaScript, он исчезает». Это зависит от того, на какую версию JavaScript у вас настроен tsc, поскольку class fields находится на продвинутой стадии (общедоступные поля включены по умолчанию в версии Chrome 8, например) и почти наверняка появятся в ближайшие месяцы, а значит, войдут в спецификацию 2020.
2. @T.J. Crowder, большое спасибо за точность, я обновлю свой ответ.