【问题标题】:"could be instantiated with an arbitrary type which could be unrelated to" in very simple example [duplicate]在非常简单的示例中,“可以用可能与之无关的任意类型进行实例化”[重复]
【发布时间】:2021-10-08 21:29:00
【问题描述】:

以下代码抛出错误:

“T”可以用与“数字”无关的任意类型实例化

interface Test {
    a: <T>() => { b: T }
}

const eg: Test = { 
    a: () => ({ b: 3})
}

Playground Link

为什么它会抛出这个错误,我怎样才能让它接受它得到的类型是它会得到的唯一类型?


正是我想要做的:

type ForeignKeyValueType = {
    foreignKey: <SCHEMA extends object>() => {
        schema: SCHEMA,
        propName: SCHEMA extends { props: any } ? KeyOf<SCHEMA["props"]> : never
    }
}

【问题讨论】:

  • 你的Test接口的a方法是一个泛型函数,也就是说调用者可以指定类型参数T为他们想要的任何东西。如果你想让 implementer 指定类型参数,那么Test 需要是一个通用的type。请参阅the answer 这个重复的问题;如果我将答案代码翻译成这个问题,我会得到this code
  • 调用者如何指定类型?来电者 (eg) 似乎已经选择不指定。
  • 来自链接的答案:“确实,有时编译器会推断这些类型参数,以便编写代码的人不必将其拼写出来,但再次,这些推断发生在调用时。”
  • 等等,eg 不是来电者。 eg 是实现。当调用eg.a 时,调用者可以指定T 为他们想要的任何值,如eg.a&lt;string&gt;()... 类型系统要求返回{b: string} 类型的值,但eg 不能去做。问题在于,eg 不能为调用者想要的任何 T 返回 {b: T} 类型的值。
  • 当你说你想要&lt;T extends object&gt;() =&gt; ({ obj: T; key: keyof T; })时,你可能真正想要的是&lt;exists T extends object&gt;{obj: T, key: keyof T},它可以像this一样间接表示,但我仍然不确定这个用例对你有多重要.如果我像这样递给你一对objkey,你唯一能做的就是obj[key],对吧?但是obj[key] 将是T[keyof T] 类型,对你来说实际上是unknown,你所能做的就是String(obj[key]) 或其他一些采用unknownany 值的操作。

标签: typescript typescript-generics


【解决方案1】:

您必须将泛型函数类型参数移动到整个接口的参数。通过这种方式,我们可以使类型参数对接口的所有其他成员可见。

interface Test<T> {
    a: () => { b: T }
}

const eg: Test<number> = { 
    a: () => ({ b: 3})
}

【讨论】:

  • 当。这对我不起作用。我的界面不需要知道任何关于泛型的事情,我不能把这个责任转嫁给我的用户。
猜你喜欢
  • 2020-11-28
  • 1970-01-01
  • 2021-10-26
  • 1970-01-01
  • 2021-01-19
  • 2021-05-11
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
相关资源
最近更新 更多