Требуется объяснение изменяющегося типа значения в TypeScript

#typescript #nestjs #typescript-typings

#typescript #nestjs #typescript-typings

Вопрос:

Я использую @nestjs/config and TypeScript в своем проекте NestJS.

Я пытаюсь получить доступ к логическому значению с помощью ключа «enabled» from .env . Если вы не знаете, что @nestjs/config такое, короче говоря, this.configService.get(<key>) считывает значение из .env .

Первая попытка:

 const enabled = this.configService
      .get<boolean>("enabled");
console.log(`${typeof enabled}`);
 

Журнал показывает enabled тип string , поэтому я понимаю, что загруженное значение всегда является строкой.

Вторая попытка:

Поскольку typeof он сообщает мне, что значение всегда равно a string , я попытался JSON.parse(...) получить логическое значение:

 const enabled = this.configService
      .get<boolean>("enabled");

console.log(`${typeof JSON.parse(enabled)}`);
 

Но компилятор жалуется:

 Argument of type 'boolean | undefined' is not assignable to parameter of type 'string'.
Type 'undefined' is not assignable to type 'string'.
 

boolean | undefined ? Разве typeof enabled он только что не сказал мне, что это за тип string ?

Вероятно, 2-я часть — это то, на что на самом деле жалуется компилятор Type 'undefined' is not assignable to type 'string'.

Третья попытка:

Я попробовал следующий код, чтобы избежать чего-либо undefined :

 const enabled = this.configService
      .get<boolean>("enabled") || '';

console.log(`${typeof JSON.parse(enabled)}`);
 

Теперь я получил новую ошибку компилятора:

 Argument of type 'string | boolean' is not assignable to parameter of type 'string'.
  Type 'boolean' is not assignable to type 'string'.`
 

На этот раз компилятор передумал, думая this.configService.get<boolean>("enabled") , что возвращает логическое значение, и поскольку я добавил || '' , возвращаемый тип является общим string | boolean .

Последняя попытка:

Чтобы сделать все это логическим, я заменил || '' на || true , код выглядит следующим образом:

 const enabled = this.configService
      .get<boolean>("enabled") || true;

console.log(`${typeof enabled}`);
 

Теперь журнал показывает мне enabled тип string . Не мог бы кто-нибудь, пожалуйста, объяснить мне, почему TypeScript, похоже, «меняет» свое мнение при выборе типа enabled ?

Как я могу вернуть логическое значение? Если значение не определено, возвращает логическое значение true

Я знаю, что в официальной документации NestJS этот пользовательский конфигурационный файл решает ту же проблему, но здесь меня в основном беспокоит поведение TypeScript, поэтому, пожалуйста, не предлагайте этого. Я хочу управлять им без пользовательского файла конфигурации.

Комментарии:

1. Ваши первые два примера кажутся одинаковыми, хотя вы говорите, что результат отличается. Я бы предположил, что по умолчанию для аргумента универсального типа используется string, и сначала вы не передавали явный аргумент, и в этом случае все остальное имеет смысл.

2. Спасибо, что указали, это была моя опечатка. Я обновил его. Я хотел бы ясно показать , что я пробовал . Когда вы говорите «все остальное имеет смысл», это относится к вам. Я надеюсь, что кто-нибудь поможет в моем вопросе. Вы какая-то роль администратора? Я вижу, что мой комментарий даже удаляют.

3. Возможно, вы просто путаете поведение во время выполнения в JavaScript (что typeof и показано) с поведением во время компиляции , с которым имеет дело TypeScript. .get<T> очевидно, вводится как возвращаемый T | undefined , потому что ключ может отсутствовать, тогда, когда вы это делаете, например || '' , вы меняете это на T | string . Но фактическое значение во время выполнения является строкой. Я не знаю, что вы имеете в виду под «ролью администратора».

4. Я понимаю, что amp; также догадался о том же. Но как решить мою проблему? Мне нужно, чтобы возвращалось логическое значение, если undefined возвращает логическое true значение, как упоминалось в моей последней попытке.

5. Ну, если вы знаете, что на самом деле будет возвращено, если ключ определен как строка, почему бы вам не использовать .get<string> ? Вы заявляете .get<boolean> об этом во время компиляции, но это, по-видимому, неверно (и, учитывая, что вы этого хотите JSON.parse , не то, что вы на самом деле хотите ). Если бы это было действительно логическое значение, типизация была бы в порядке: tsplay.dev/w2EQ8W .