Почему тип свойства не присваивается при передаче через const в машинописном тексте?

#typescript

Вопрос:

Я знаю, что это на 100% глупый вопрос, но я не могу справиться с собой и хочу знать ответ.

 type SweetAlertPosition =
    'top' | 'top-start' | 'top-end' | 'top-left' | 'top-right' |
    'center' | 'center-start' | 'center-end' | 'center-left' | 'center-right' |
    'bottom' | 'bottom-start' | 'bottom-end' | 'bottom-left' | 'bottom-right';
 

Основной интерфейс(упрощенный):

 interface SweetAlertOptions {
    ...,
    position?: SweetAlertPosition
}
 
 class Swal {
    mixin(options: SweetAlertOptions)
}
 

Теперь, если я явно передам параметры вызову .mixin: Swal.mixin({ позиция: «внизу»}) — ошибки нет.
Но если я заранее определяю параметры в некотором объекте const:

 defaultOptions = {
   position: 'bottom'
}
 

Проходя сейчас, сделайте ошибку — Swal.mixin(defauiltOptions)

 Types of property 'position' are incompatible.
Type 'string' is not assignable to type '"top" | "top-start" | "top-end" | "top-left" | "top-right" | "center" | "center-start" | "center-end" | "center-left" | "center-right" | "bottom" | "bottom-start" | "bottom-end" | "bottom-left" | "bottom-right" | undefined'.
 

Я уже выяснил, что a должен привести строковый тип к const:

 defaultOptions = {
    position: 'botton' as const | as SweetAlertPosition
}
 

Но почему передача параметров через const obj(defaultOptions) делает свойство position строковым, а передача его напрямую не приводит к oO ?

Ответ №1:

При объявлении const переменной ее тип выводится только из значения, которое вы ей присваиваете, а не из того, где используется переменная (вывод полного типа). При инициализации переменной литералом объекта типы свойств расширяются, чтобы вы могли добавлять к ним другие строки или числа, если только вы не сузите их as const .

При передаче литерала объекта в качестве аргумента его тип выводится из типов параметров вызываемой функции.

В вашем случае я бы не писал as const , но рекомендовал

 const defaultOptions: SweetAlertOptions = {
   position: 'bottom'
};
 

Ответ №2:

Проблема в том, что у этого defaultOptions есть тип { position: string } , если вы не сделаете что-то с этим, как это:

 const defaultOptions: SweetAlertOptions = {
   position: 'bottom'
}
 

Здесь мы явно объявляем, что defaultOptions это тип SweetAlertOptions , и тогда при переходе в нет ошибки mixin .

В примере явной передачи значения компилятор может интерпретировать объект в контексте вызова.

Пример в машинописной игровой площадке