Typescript 未推断扩展接口的泛型类型

Typescript 未推断扩展接口的泛型类型,typescript,generics,types,type-inference,Typescript,Generics,Types,Type Inference,在下面的示例中,Typescript可以根据在bar中传递给它的参数推断方法foo中T的类型,但它不会推断它感觉应该推断的R的类型,因为它知道T的类型,并且T扩展了I 接口I{ } A级执行器I{ } 函数foo(bar:T):R{ 返回; } foo(新A()); 还有其他方法吗?第一个问题是您的接口是空的,typescript使用结构类型,因此如果您的泛型接口不使用它的类型参数,那么它是否拥有它就无关紧要了。例如,这项工作: interface I<T> { } declare

在下面的示例中,Typescript可以根据在
bar
中传递给它的参数推断方法
foo
T
的类型,但它不会推断它感觉应该推断的
R
的类型,因为它知道
T
的类型,并且
T扩展了I

接口I{
}
A级执行器I{
}
函数foo(bar:T):R{
返回;
}
foo(新A());

还有其他方法吗?

第一个问题是您的接口是空的,typescript使用结构类型,因此如果您的泛型接口不使用它的类型参数,那么它是否拥有它就无关紧要了。例如,这项工作:

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

您也可能只想从实现中提取它

例如


我想补充一下@Titan的公认答案。您还可以在界面上添加隐藏符号,以欺骗结构类型

我在我的项目中使用了以下内容,编译器能够推断出我操作的结果类型。你可以在厨房里试试

const F=Symbol();
界面作用{
[F] ?:R;//编译器会使用此技巧
}
类型ActionResult=T扩展操作?R:从来没有;
接口SetName扩展操作{
类型:“设置_名称”;
名称:字符串;
}
接口SetNameResult{
类型:'设置\名称\结果';
newName:string;
}
功能过程(动作:A):动作结果{
以任意形式返回{};//TODO process action并返回有效结果
}
const r=process({type:'set_name',name:'the name'}作为SetName);
r、 类型;/'设置\u名称\u结果'
r、 newName;//一串

这太酷了,谢谢,接下来的问题是,是否可以将此
提取自
映射类型设置为泛型?因此,它可以从任何接口而不是具体的I?@IBOED2中提取。不幸的是,不,您需要为要从中提取参数的每个泛型类型定制一个专用的条件类型。
interface I<T> { }
declare let foo: I<string> 
declare let bar: I<number>
// Same structure ({}), assignment works
foo = bar
bar = foo 
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
export class CatWatcher extends Watcher<Cat>
{
    watch(): Cat { ... }  // overridden from base
}
export type ExtractWatcherType<T> = T extends { watch: infer W } ? W : never;