【问题标题】:why am I having trouble assigning properties with varying types?为什么我无法分配不同类型的属性?
【发布时间】:2022-02-17 08:59:10
【问题描述】:

我正在尝试将类实例成员属性设置为接受动态值的类型化对象的值。类实例成员属性是布尔值,而我在对象上设置的值是布尔值...

interface Cat {
  [ index: string ] : string | number | boolean
}

class Test {
  private result : boolean | undefined;

  doIt () {
    let c: Cat = { purring: true }
    this.result = cat.purring;
  }
}

我在尝试分配 this.result 的行上遇到错误:

键入'字符串 |号码 | boolean' 不能分配给类型 'boolean | 不明确的'。类型 'string' 不可分配给类型 'boolean | 未定义'。

我似乎只有这样做才能完成这项工作:

this.result = cat.purring as boolean;

我希望我不必这样做...? ...

还有一个类似的问题,我只是想允许一个字符串数组的值或者一个字符串数组的数组:

type StringOrNestedString = string[] | StringOrNestedString[]

interface Item {
  filters: StringOrNestedString,
}

let i: Item = {
  filters: ['foo', ['bar']],
}

我得到:

类型 '(string | string[])[]' 不可分配给类型 'StringOrNestedString'。 类型 '(string | string[])[]' 不可分配给类型 'string[]'。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    错误是合法的; cat 可以是一个对象,其属性可以是string | number | boolean,但Test#result 可以是boolean | undefined。想象一下维恩图,你会发现只有Cat 的一个子集可以分配给Test#result:只有当它是一个布尔值时。

    什么打字稿警告你:

        let cat: Cat = { purring: true }
        // this is allowed
        cat.purring = 123
        // which means that this should error out
        this.result = cat.purring;
    

    所以,缩小范围以处理这种情况:

        if (typeof cat.purring !== 'boolean') {
          // throw or somethihng
          return
        }
    
        this.result = cat.purring;
    

    关于递归类型:

    type StringOrNestedString = string | Array<StringOrNestedString | string> 
    

    【讨论】:

    • 最终这来自一个 api,它总是布尔值......在这种情况下必须防范类型对我来说似乎很愚蠢......所以我猜想转换为布尔值是我的最好的选择?
    • 如果可能的话,我真的会尽量避免强制转换,而是尝试更正/修改/修补类型以反映您的期望。它很可能是一个非常简单的const cat = toCat(myVeryBroadApiResponse) // this doesn't need to do much rather than return a type that make sense for the consumer, narrowing it down, and it serve as an anti corruption layer of sort。一旦你用一堆as 乱扔代码,你就会与类型系统作斗争,而且你不会得到大部分好处
    • sigh.. 好的.. 我真的很努力使用打字稿(将 angularJS 转换为 angular),而且事实证明这并不容易。我刚刚提出的关于字符串数组的另一个问题是,该属性也可以是一个函数……所以我真正想要的是:interface XYZ { filters: Array&lt;string | string[]&gt; | (arg0: any) =&gt; void }。但是尽管有 if (typeof x.filters === 'function') { x.filters(someArg) } 的代码,我得到:`不是所有类型的成分 '(string | string[])[] | ((arg0: any) => void)' 是可调用的。`如果我明确检查类型,为什么会发生这种情况?
    猜你喜欢
    • 1970-01-01
    • 2021-06-22
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    • 1970-01-01
    • 2022-12-12
    • 1970-01-01
    相关资源
    最近更新 更多