【问题标题】:Why property type unassignalbe while passing via const in TypeScript?为什么在 TypeScript 中通过 const 传递属性类型 unassignalbe?
【发布时间】:2021-04-05 12:37:45
【问题描述】:

我知道这是一个 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({ position: 'bottom' }) - 没有错误。 但是如果我在某个 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'.

我已经发现必须将 String 类型转换为 const:

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

但是为什么通过 const obj(defaultOptions) 传递选项会使 position 属性变成 String 类型,而直接传递却不是 oO 呢?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    在声明const 变量时,其类型仅源自您分配给它的值,而不是源自变量的使用位置(完整类型推断)。使用对象字面量初始化变量时,属性类型为 widened,因此您可以将其他字符串或数字分配给它们 - 除非您使用 as const 缩小它们的范围。

    当传递一个对象字面量作为参数时,它的类型是从被调用函数的参数类型推断出来的。

    在你的情况下,我不会写 as const 但推荐

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

    【讨论】:

      【解决方案2】:

      问题是defaultOptions 的类型是{ position: string },除非你对它做点什么,像这样:

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

      在这里,我们明确声明defaultOptions 的类型为SweetAlertOptions,然后传入mixin 时不会出错。

      在显式传入值的示例中,编译器可以在调用的上下文中解释对象。

      TypeScript Playground 中的示例

      【讨论】:

        猜你喜欢
        • 2015-03-24
        • 1970-01-01
        • 1970-01-01
        • 2012-07-09
        • 2019-05-10
        • 1970-01-01
        • 2016-01-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多