【问题标题】:Recursive type definitions does not seem to work handle generics?递归类型定义似乎无法处理泛型?
【发布时间】:2018-01-23 04:03:30
【问题描述】:

我认为这是 Typescript 中的一个错误,我将其提交为问题 here。我不希望它被修复(至少不会很快,所以我想问你们,有没有人碰巧有一个比 create_1 更好的解决方案/解决方法的想法?

代码

type RecursivePartial<T> = {
    [P in keyof T]?: RecursivePartial<T[P]>;
};

type State<T> = { value: T };

function create_1<T>(){

    let _x: RecursivePartial<State<T>>;
    let _y: State<RecursivePartial<T>>;

    _x = _y;
}

function create_2<T>(){
 /*

 */

    let x: RecursivePartial<State<T>>;
    let y: State<T>;

    /*
        Type 'State<T>' is not assignable to type RecursivePartial<State<T>>'.
            Types of property 'value' are incompatible.
                Type 'T' is not assignable to type RecursivePartial<T>[P]>'.
                    Type 'T[string]' is not assignable to type 'RecursivePartial<T[P]>'.
    */

    x = y; 
}

预期行为: 我曾期望第二个示例是有效的打字稿,即 State 应该可以分配给 RecursivePartial>。应该是这种情况,因为任何状态都将是它自身的一部分,因为 T 是相同的类型。

实际行为: 我得到一个类型错误(见上文),似乎递归类型定义在遇到泛型时会中断?

TS Playground 链接 代码和类型错误可以在这里确认; ts-playground example

【问题讨论】:

  • 作为信息:基于当前版本 2.4 的文档,类型别名不允许使用 Recusive Types typescriptlang.org/docs/handbook/advanced-types.html "但是,类型别名不可能出现在右侧的其他任何地方声明……”
  • @Magu,我认为这与这里无关;递归类型只在属性中提及自己,这是允许的。 (类型编译没有错误的事实表明它很好)。这里的怪异与类型检查有关。
  • @tugend,我在使用的 2.5.0-dev.20170627 版本的打字稿上没有看到这个错误。也许它是固定的?目前无法追踪它
  • 使用 typescript@rc 时问题仍然存在。我应该尝试与 RC 不同的版本吗?如何获得?我在“github.com/Microsoft/TypeScript”上找不到任何类似的标签。
  • 感谢您在此跟进。

标签: typescript generics recursion types partial


【解决方案1】:

对我来说它看起来像一个错误。解决方法:

正如我在the Github issue 中注意到的,第一个也是最好的解决方法可能是打开strictNullChecks compiler option。我真的建议将其打开并保持打开状态,因为它非常有用。


如果您不想这样做,您可以随时使用type assertion 告诉编译器您比它更了解类型。如果编译器真的不愿意做一个断言,你可以通过any的断言来传递它,就像这样:

function create_2<T>(){
    let x: RecursivePartial<State<T>>;
    let y: State<T>;
    x = y as any as RecursivePartial<State<T>>; // I know it!
}

如果您不想这样做,可以将RecursivePartial&lt;&gt; 的定义更改为以下内容:

type RecursivePartial<T> = {
    [P in keyof T]?: T[P] | RecursivePartial<T[P]>;
};

我相信这实际上是同一件事,但编译器更容易看到您始终可以将 T 类型的值分配给 RecursivePartial&lt;T&gt; 类型的变量。


希望对您有所帮助。祝你好运!

【讨论】:

  • 我们希望等待设置 strictNullChecks,因为我们必须更改多少代码库。不过,所有三种解决方案都有效。谢谢! =D。我们现在很可能会采用最后一种解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多