#typescript
Вопрос:
Каков наилучший маршрут для выполнения следующих действий в машинописном тексте:
У меня есть объект, который выглядит следующим образом:
export interface TestConfig {
configSql: MsSqlDatabaseConfig | undefined;
userSql: MsSqlDatabaseConfig | undefined;
}
Позже я хочу создать массив из двух конфигураций в объекте, например
let dbConfigs: MsSqlDatabaseConfig[] = [config.configSql, config.userSql];
Однако Машинопись сообщает об этом MsSqlDatabaseConfig | undefined is not assignable to type MsSqlDatabaseConfig
, что имеет смысл.
Но если я ранее гарантировал в своем коде, что эти значения не являются неопределенными, каков наилучший способ разрешить компилятору использовать эти значения в моем массиве? Мне нужны | undefined
асинхронные вызовы, которые извлекают данные, и я не могу использовать асинхронные методы в конструкторе класса, поэтому значения должны начинаться как неопределенные.
Приведение типов двух значений похоже на то, что я включаю типы в массив.
let dbConfigs: MsSqlDatabaseConfig[] = [<MsSqlDatabaseConfig> config.configSql, <MsSqlDatabaseConfig> config.userSql];
Есть ли лучший способ?
Редактировать
Сначала вызывается метод resetDatabaseToKnownState (), который извлекает некоторые значения из моего файла env и анализирует их в допустимый объект. Значения configSql и userSql затем отображаются с этого момента и далее.
public async resetDatabaseToKnownState(): Promise<void> {
// Setup
this.testConfig = await this.getSetupConfig();
}
private async getSetupConfig(){
let configSql: MsSqlDatabaseConfig = JSON.parse(process.env.configDatabaseInfo!);
let userSql: MsSqlDatabaseConfig = JSON.parse(process.env.userDatabaseInfo!);
return {
configSql: configSql,
userSql: userSql
}
}
Комментарии:
1. «Но если я ранее гарантировал в своем коде, что эти значения не являются неопределенными…» В обычном случае TypeScript может увидеть, что вы это сделали, сузить тип для вас и не вызывать ошибку. Можете ли вы показать нам, как вы это сделали? Возможно, мы сможем помочь вам понять, почему TypeScript не может его увидеть.
2. @Ти Джей Краудер, я обновил операцию. Я знаю об
!
операторе, однако я стараюсь, чтобы мой код не был завален ими. Однако, похоже, я не могу иметь это в обоих направлениях3. Исправление того, что вы описали, звучит так, как будто это потребует больших изменений, чем мы можем предложить здесь (например, найти способ не иметь одного и того же объекта: А) возможно, имеют неопределенные значения и Б) определенно не имеют неопределенных значений). Возможно, вместо того, чтобы иметь побочный эффект,
resetDatabaseToKnownState
можно было бы вернуть известную-не-будущую-undefined
версию объекта? Что-то в этом роде. Возможно, это невозможно, и, если возможно, это может быть большим изменением, чем вы можете сделать прямо сейчас, но это именно то, что нужно. 🙂 Удачи!
Ответ №1:
Но если я гарантировал ранее в своем коде, что эти значения не являются неопределенными…
В обычном случае TypeScript может видеть, что вы это сделали, сузить тип для вас и не вызывать ошибку. Например:
function example(x: {value: string | undefined}) {
if (x.value) {
console.log(x.value.toLocaleLowerCase()); // No error
}
}
Таким образом, вы можете настроить свой код так, чтобы TypeScript мог видеть, что вы сузили тип.
В редкой ситуации, когда вам нужно выполнить утверждение, проще всего использовать !
постфиксный оператор машинописного текста «not null или undefined».:
let dbConfigs: MsSqlDatabaseConfig[] = [config.configSql!, config.userSql!];
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^−−−−−−−−−−−−−−−−^
!
это утверждение типа, поэтому, как и все утверждения типа, его лучше избегать, где это возможно. Иногда для этого требуются более значительные структурные изменения, чем в простом примере, показанном выше.