【问题标题】:Using union types with a function not accepting arguments as an object将联合类型与不接受参数作为对象的函数一起使用
【发布时间】:2019-07-12 16:19:19
【问题描述】:

下面是一个使用联合类型的函数。

type Shape = 
  { kind: 'circle', radius: number } |
  { kind: 'rectangle', w: number, h: number }

const getArea = (shape: Shape) => {     // this works
  switch(shape.kind) {
    case 'circle':
      return Math.PI * shape.radius ** 2
    case 'rectangle':
      return shape.w * shape.h
  }
  throw new Error('Invalid shape')
}

getArea({ kind: 'circle', radius: 10 })

它接受参数作为对象,因此它可以工作。

但是当函数不接受参数作为对象时,我该怎么做。请参考以下示例

type Shape = 
  { (kind: 'circle', ...args: [number]) } |
  { (kind: 'rectangle', ...args: [number, number]) }

const getArea: Shape = (kind, ...args) => {     // this doesn't work
  switch(kind) {
    case 'circle':
      return Math.PI * args[0] ** 2
    case 'rectangle':
      return args[0] * args[1]
  }
  throw new Error('Invalid shape')
}

getArea('circle', 10)
getArea('rectangle', 5, 5)

另外,我可以这样写

const getArea: Shape = (kind: 'update' | 'reset', ...args: [number] | [number, number]) => {

但它不会给我完整的类型安全性。如第一个示例所示,我希望在 kind 更改时更改 args。

或者对于这类问题有什么不同的方法?

【问题讨论】:

    标签: typescript types union-types


    【解决方案1】:

    你可以这样写

    const getArea = (...[key, ...args]: ['circle', number] | ['rectangle', number, number]) => {
        switch (key) {
            case 'circle':
                return Math.PI * args[0] ** 2
            case 'rectangle':
                return args[0] * args[1]
        }
        throw new Error('Invalid shape')
    }
    

    const getArea = (...args: ['circle', number] | ['rectangle', number, number]) => {
        switch (args[0]) {
            case 'circle':
                return Math.PI * args[1] ** 2
            case 'rectangle':
                return args[1] * args[2]
        }
        throw new Error('Invalid shape')
    }
    

    【讨论】:

    • 实施您的解决方案后,它说“休息元素不能包含绑定模式。”
    • 你使用哪个 TypeScript 版本?
    • 我的 TypeScript 版本是 3.3.1
    • 那就奇怪了,我的ts版本是3.2.2居然可以用
    • 他们甚至在这里有一个问题github.com/Microsoft/TypeScript/pull/26017
    猜你喜欢
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 2019-08-12
    • 1970-01-01
    相关资源
    最近更新 更多