Машинопись выводить строковый литерал из троичного условного
Это упрощенный пример:
function doSomething(animal: 'bird' | 'fish'){ }
let flies=true;
const animal = flies ? 'bird' : 'fish'
doSomething(animal);
Typescropt выводит тип "птица" | "Рыба" в отведении к животному из тройной условно. (если бы животное не было константным, оно жаловалось бы, так как выводило бы строку типа, которую нельзя присвоить 'bird' | 'fish')
Но
const parms ={
animal: flies ? 'bird' : 'fish'
}
doSomething(parms); /* Argument of type '{ animal: string; }' is not
assignable to parameter of type '{ animal: "bird" | "fish"; } */
Здесь выводится строка из троичной условности. Есть ли способ сохранить вещи в этом стиле (то есть не нужно определять тип и объявлять полевое животное как этот тип)
1 ответ
Typescript выводит только строковые литеральные типы в определенной ситуации. Свойство, как правило, не является одним из таких случаев, если только нет дополнительных обстоятельств, чтобы намекнуть литеральный тип для свойства. (это не имеет ничего общего с троичным оператором).
В Typescript 3.4 (не выпущен на момент написания, но уже доступен как typescript@next
в npm
) вы сможете намекнуть компилятору, что вы хотите, чтобы объектные литералы были выведены в соответствии с этой проблемой:
let flies=true;
//types as { readonly animal: "bird" | "fish"; }
const parms ={
animal: flies ? 'bird' : 'fish'
} as const
В версии 3.3 и ниже вы можете использовать функцию, чтобы сообщить компилятору, что вы хотите сделать вывод литерального типа:
let flies=true;
function withLiteralTypes<T extends Record<string, P>, P extends string | number | null | boolean | Record<string, P>> (o: T) {
return o;
}
// types as { animal: "bird" | "fish"; }
const parms =withLiteralTypes({
animal: flies ? 'bird' : 'fish',
})