Generic type of extended interface not inferred

2019-07-19 12:00发布

In the following example Typescript can infer the type of T in method foo from the parameter passed to it in bar, but it doesn't infer the type of R, which it feels like it should - given that it knows the type of T and also that T extends I<R>

interface I<T> {
}

class A implements I<string> {

}

function foo<T extends I<R>, R>(bar: T): R {
    return;
}

foo(new A());

Is there another way to do this?

1条回答
狗以群分
2楼-- · 2019-07-19 12:30

The first problem is that your interface is empty, typescript uses structural typing so if your generic interface will not use it's type parameter it won't matter much that it has it. For example this works:

interface I<T> { }
declare let foo: I<string> 
declare let bar: I<number>
// Same structure ({}), assignment works
foo = bar
bar = foo 

Event if we add a field, Typescript will still not infer the R type parameter, it just doesn't try to extract it from T. Your best option is to use a conditional type and extract the generic type parameter where you need it:

interface I<T> {
    value :T 
}

class A implements I<string> {
    value! :string 
}

type ExtractFromI<T extends I<unknown>> = T extends I<infer U> ? U : never;
function foo<T extends I<unknown>>(bar: T):  ExtractFromI<T>{
    return bar.value as ExtractFromI<T>; // Generic type with unresolved type parameters, we need a type assertion to convince the compiler this is ok 
}
var r = foo(new A()); // string
查看更多
登录 后发表回答