2017-05-05 135 views
1

这是超出了TypeScript能够做的能力还是我做了一些非常错误的事情?下面是一些代码,我会想有工作:打字稿子类型推断

interface ISquare { 
    area: number; 
} 

interface ICircle { 
    radius: number; 
} 

abstract class Morph<T1, T2> { 
    firstOption: T1; 
    secondOption: T2; 
} 

class CircleAndSquare extends Morph<ICircle, ISquare> { } 

function returnSecondOption<TMorph extends Morph<T1, T2>, T1, T2> (morph: TMorph): T2 { 
    return morph.secondOption; 
} 

returnSecondOption(new CircleAndSquare()) // adding a . here should give me intellisense for a square 

智能感知应显示ISquare当我把一个点在函数调用returnSecondOption结束的成员,但它没有,它似乎将T1和T2视为{}

回答

0

事情是,extends为泛型参数使一个非常弱的约束。

换句话说,TMorph extends Morph<T1, T2>没有提供足够的信息来推断secondOptionTMorph总是T2,因为例如TMorph可以扩展这样的:

class BadMorph extends Morph<ICircle, ISquare> { 
    secondOption: ISquare & { radius: string } 
} 

secondOption是不是一个真正的ICircle了,因为radius现在是number & string,它基本上相当于{}

另一件事是,TMorph泛型参数是不是真的有必要在returnSecondOption,因为它是目前写的问题,所以你可以摆脱它:

function returnSecondOption<T1, T2> (morph: Morph<T1, T2>): T2 { 
    return morph.secondOption; 
} 

它将采取任何与Morph<T1, T2>兼容反正,和推理作品

let s = returnSecondOption(new CircleAndSquare()); 

在打字稿操场上被显示为s: ISquare提示。

如果您确实需要在returnSecondOption中为其参数的确切类型命名,我不知道如何进行推理。你可以尝试

function returnSecondOptionGeneric2<TMorph, T1, T2> (morph: TMorph & Morph<T1, T2>): T2 { 
    return morph.secondOption; 
} 

但我不确定这个变种允许做什么。

+0

'function returnSecondOption (morph:Morph ):T2' is correct。我没有看到任何更复杂的事情是由OP中的情况所保证的。 –