如何对数组类型的并集执行操作?

huangapple go评论58阅读模式
英文:

How to perform operations on union of array types?

问题

以下不起作用

type Foo = number[]
type Bar = string[]

function move(x: Foo | Bar) {
    const v = x.splice(0, 1)
    x.splice(1, 0, ...v)
}

因为显然 vnumber[] | string[] 类型,不能分配给数字或字符串。我该如何解决这个问题?

英文:

The following doesn't work

type Foo = number[]
type Bar = string[]

function move(x: Foo | Bar) {
    const v = x.splice(0, 1)
    x.splice(1, 0, ...v)
}

Because apparently v is number[] | string[] and is not assignable to either number or string. How do I work around this?

答案1

得分: 1

如果类型无关,使用 unknown

由于这是对数组进行完全通用的操作(移动一些元素),数组的实际类型不重要。只需声明该函数接受任何unknown[]Array<unknown>可以工作的数组即可:

type Foo = number[]
type Bar = string[]

function move(x: unknown[]) {
    const v = x.splice(0, 1)
    x.splice(1, 0, ...v)
}

declare const arr: Foo | Bar;
move(arr); //OK

Playground链接

如果类型可能重要,使用泛型

如果也包括类型有意义,使用泛型并将其约束为仅限数组可能更合理:

type Foo = number[]
type Bar = string[]

function move<T extends Array<unknown>>(x: T) {
    const v = x.splice(0, 1)
    x.splice(1, 0, ...v)
}

declare const arr: Foo | Bar;
move(arr); //OK

Playground链接

这可能对指定调用中期望的类型很有用,如果类型不匹配,它将引发编译错误:

move<string[] | number[]>(arr);             // OK
move<string[] | number[] | boolean[]>(arr); // OK
move<string[] | boolean[]>(arr);            // error
move<string[]>(arr);                        // error

Playground链接

英文:

Use unknown if the type does not matter

Since this is a completely generic operation on an array (moving some elements), the actual type of the array is irrelevant. It is enough to declare that the function accepts any array where unknown[] or `Array<unknown> would work:

type Foo = number[]
type Bar = string[]

function move(x: unknown[]) {
    const v = x.splice(0, 1)
    x.splice(1, 0, ...v)
}

declare const arr: Foo | Bar;
move(arr); //OK

Playground Link

Use a generic if the type may matter

If it makes sense to also include the type, use a generic and constrain it to only arrays:

type Foo = number[]
type Bar = string[]

function move&lt;T extends Array&lt;unknown&gt;&gt;(x: T) {
    const v = x.splice(0, 1)
    x.splice(1, 0, ...v)
}

declare const arr: Foo | Bar;
move(arr); //OK

Playground Link

This might be useful to specify the types expected in a call which will then raise a compilation error if they do not match:

move&lt;string[] | number[]&gt;(arr);             // OK
move&lt;string[] | number[] | boolean[]&gt;(arr); // OK
move&lt;string[] | boolean[]&gt;(arr);            // error
move&lt;string[]&gt;(arr);                        // error

Playground Link

huangapple
  • 本文由 发表于 2023年5月29日 19:52:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76357131.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定