Можно ли обойтись без кастования типов при присваивании строки переменной с литеральным типом?

Доброго дня.
Есть тип, описывающий небольшой объект. По замыслу это должна быть константа.
declare type KDFEncryptOptions = {
  kdf: 'scrypt',
  n: 8192,
};


Однако, когда я тайпаю этим типом аргумент функции, я вижу сообщение "Type `string` is not assignable to type `scrypt`". Нашел решение, которое предполагает кастование типа при присваивании.
somefunction(encryptOptions as KDFEncryptOptions);
Но оно не подходит ввиду одной фундаментальной причины: в проекте ts используется только для design-time, только с описанием типов в декларационных файлах. Маразм? Да. Но как-то быть надо.

Как быть? Есть ли способы объявить строгий тип со строковым литератом, и при этом позволить строки (при условии, что они совпадут с литералом)? Или, может быть, можно настроить компилятор, чтобы он более лояльно относился к таким кейсам?

Заранее спасибо.
  • Вопрос задан
  • 69 просмотров
Решения вопроса 2
Xuxicheta
@Xuxicheta
инженер
попробуй так. мож прокатит
/**
 * @template {string} T
 * @param {T} encryptOptions
 */
function somefunction(encryptOptions)


это равнозначно в ts
function somefunction<T extends string>(encryptOptions: T)

правда если ты передаешь объект, нужно будет сделать отдельный тип с дженериком чисто для этой функции.
Ответ написан
Heian
@Heian Автор вопроса
Ашот
Нужно воспользоваться специальной директивой. Это равнозначно касту, но не является таковым на уровне программного кода.
await asyncFunction(
  /** @type {DesiredType} */ (argument)
);
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@tosha4encko
Так вам нужно, чтобы тип encryptOptions был KDFEncryptOptions -
declare interface KDFEncryptOptions {
  kdf: 'scrypt';
  n: 8192;
}

function somefunction(encryptOptions: KDFEncryptOptions) {
  console.log('!!!');
}

let a: KDFEncryptOptions = { kdf: 'scrypt', n: 8192 };

somefunction(a);
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы