#typescript #typescript4.0
#typescript #typescript4.0
Вопрос:
У меня есть свойство класса, которое создается с начальным значением:
private _httpClient: ClientInterface = new HttpURLConnectionClient();
который я хочу переопределить, если он передан при создании экземпляра класса:
class Class {
private _httpClient: ClientInterface = new HttpURLConnectionClient();
constructor(httpClient?: ClientInterface) {
if (httpClient) {
this._httpClient = httpClient // replaces existing _httpClient
}
}
}
new Class(httpClient)
Я переношу этот код на TypeScript 4, и я предположил, что следующее будет эквивалентно:
class Class {
private _httpClient: ClientInterface = new HttpURLConnectionClient();
constructor(httpClient?: ClientInterface) {
this._httpClient ||= httpClient // Shows ts error! But should be equivalent to this._httpClient = httpClient || this._httpClient
}
}
new Class(httpClient)
но он отображается Type 'X | undefined' is not assignable to Type 'X'
, что понятно, если я не использовал логическое или.
Я знаю, что смогу решить эту проблему, если сделаю это, но я хочу понять, почему в приведенном выше решении отображается ошибка типа:
class Class {
private _httpClient: ClientInterface;
constructor(httpClient?: ClientInterface) {
this._httpClient = httpClient || new HttpURLConnectionClient()
}
}
new Class(httpClient)
Комментарии:
1. Я не вижу ошибки на игровой площадке , поскольку я ожидаю
if (httpClient)
, что она сужается отClientInterface | undefined
доClientInterface
.2. Я думаю, вы пропустили весь вопрос. Эта часть кода в порядке. Я хочу заменить его на приведенный ниже, используя логическое или
||=
, которое выдает: typescriptlang.org/play ? #code/…3. О, я понимаю, что вы имеете в виду, извините — примечание
||=
касается того, что левая сторона , возможно, не определена, а не правая сторона. Этоa = a || b
неa = b || a
так .4.Вы можете упростить все это, чтобы
constructor(private _httpClient: ClientInterface = new HttpURLConnectionClient())
typescriptlang.org/play ?#code/…
Ответ №1:
Вы немного неверно истолковали, что делает назначение короткого замыкания. a ||= b
эквивалентно a = a || b
, оно имеет дело с тем, что левая часть присваивания, возможно, не определена, а не с правой частью.
В вашем случае это что-то вроде:
this._httpClient = this._httpClient || httpClient
(Компилятор фактически выдает this._httpClient || (this._httpClient = httpClient)
, но так проще думать об этом.)
Ваша последняя версия наоборот ( a = b || a
):
this._httpClient = httpClient || new HttpURLConnectionClient()
// ^ equivalent to this._httpClient
Вероятно, самым простым способом реализовать это было бы использовать свойство параметра со значением по умолчанию:
class Class {
constructor(private _httpClient: ClientInterface = new HttpURLConnectionClient()) { }
}