简体   繁体   English

与通用接口一起使用时,Typescript 无法正确推断类型

[英]Typescript is not infering type correctly when used with generic interface

Here is my code :这是我的代码:

import {FieldType} from '/imports/common/core/schema/Schema';

interface Content<S, F extends keyof S> {
  name: F
  type: FieldType | Container<S[F]>
}

class Container<S> {
  content: Content<S, keyof S>;

  constructor(content: Content<S, keyof S>) {
    this.content = content;
  }
}

type Parent = {
  height: number
};

type Child = {
  age: number
  parent: Parent
}

const containerParent = new Container<Parent>({
  name: 'height',
  type: FieldType.String
});

new Container<Child>({
  name: 'parent',
  type: containerParent // This line fails....
});

You can try it here :你可以在这里尝试:

Exemple 例子

I want to know how I could make TS to infer that the value I want the "type" property to expect to receive a Container, because I set the name to 'parent' the line before.我想知道如何让 TS 推断出我希望“类型”属性期望接收容器的值,因为我将名称设置为之前的“父”行。 For now it waits for a Container<number |现在它等待 Container<number | Parent>...家长>...

Edit:编辑:

Updated exemple 更新示例

The problem is that Content is based on a specific key of S , but Container uses all keys of S for its type instead of any specific key.问题是Content基于S的特定键,但Container使用S所有键作为其类型,而不是任何特定键。 So the type of the constructor argument is expected to be string | Container<S[keyof S]>所以构造函数参数的type应该是string | Container<S[keyof S]> string | Container<S[keyof S]> . string | Container<S[keyof S]>

The errors go away if you change Container to take a second generic for the key.如果您将Container更改为密钥的第二个泛型,错误就会消失。 You can make that second variable optional and have default to keyof S so that you don't need to change Container<Parent> .您可以将第二个变量keyof S可选并默认为keyof S这样您就无需更改Container<Parent>

class Container<S, F extends keyof S = keyof S> {
  content: Content<S, F>;

  constructor(content: Content<S, F>) {
    this.content = content;
  }
}

With the current setup, you do have to set the key generic on the child container for it to work.使用当前设置,您必须在子容器上设置通用密钥才能使其工作。 You can't tell typescript to infer the second type while explicitly setting the first.您不能在明确设置第一个类型时告诉打字稿推断第二个类型。

new Container<Child, 'parent'>({
  name: 'parent',
  type: containerParent
});

Playground Link游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM