“未知”类型不可分配给“数字”类型

问题描述 投票:0回答:1

当我尝试实现这样的事情时遇到

Type 'unknown' is not assignable to type 'number'

interface Foo<V = unknown> {
    foo: (value: V) => void
}

class Bar implements Foo<number> {
    foo(v: number) {}
}

function test(foo: Foo): void {}

test(new Bar) // complains:

// Argument of type 'Bar' is not assignable to parameter of type 'Foo<unknown>'.
//   Types of property 'foo' are incompatible.
//     Type '(v: number) => void' is not assignable to type '(value: unknown) => void'.
//       Types of parameters 'v' and 'value' are incompatible.
//         Type 'unknown' is not assignable to type 'number'.(2345)

为什么它会这样,考虑到

test
应该能够获得
Foo
的不同实现,例如

,我该如何重新设计它
class Bar2 implements Foo<string> {
    foo(v: string) {}
}
  • 输入断言:

    test(new Bar as Foo) // it doesn't complain now, but imo it's dirty and bad DX workaround
    
  • 尝试将

    unknown
    中的
    Foo
    替换为联合类型,例如
    string | number | ...
    ,但没有帮助。

typescript
1个回答
0
投票

实际上,这里的主要问题是

unknown
不能 被分配给除了它本身和
any
类型之外的任何东西。

如果你进一步简化你的示例

type FooFn = (value: unknown) => void
const testFooFn: FooFn = (n: number) => {} // Error 

您会遇到与上面类似的错误。

Type '(n: number) => void' is not assignable to type 'FooFn'.
  Types of parameters 'n' and 'value' are incompatible.
    Type 'unknown' is not assignable to type 'number'.

正如评论中所建议的,一种选择是使用泛型来继承类型。

interface Foo<V = unknown> {
  foo: (value: V) => void
}

class Bar implements Foo<number> {
  foo(v: number) {
    console.log(v)
  }
}

function test<T>(foo: Foo<T>): void {}

test(new Bar()) // No Error

另一个选项是将

unknown
更改为
any
。请参阅此处的差异,但通常使用
unknown
更好/更安全,但需要更多类型体操。

interface Foo<V = any> {
  foo: (value: V) => void
}

class Bar implements Foo<number> {
  foo(v: number) {
    console.log(v)
  }
}

function test(foo: Foo): void {}

test(new Bar()) // No Error

参见TSPlayground

© www.soinside.com 2019 - 2024. All rights reserved.