递归类型定义似乎不起作用处理泛型?

时间:2017-08-15 08:39:02

标签: typescript generics recursion types partial

我认为这是打字稿中的一个错误,我将其作为问题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&gt;。这应该是这种情况,因为任何国家都是自己的一部分,因为T是同一类型。

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

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

1 个答案:

答案 0 :(得分: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<>的定义更改为以下内容:

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

我认为,这实际上是相同的,但编译器可以更容易地看到您始终可以将T类型的值分配给RecursivePartial<T>类型的变量。

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