TL;DR:打字稿中没有? 语法。如果你可以使用除any 之外的任何东西,这真的取决于你的泛型类型的变化,但你可能会使用any 类通常最终是不变的。
从本质上讲,这是一个差异问题。如果您想了解更多信息,可以查看我的演讲here
如果类是 co-varinat,您可以使用 ElaborateStuff 并且 SomeStuff 的任何实例化都将与它兼容,因为 SomeStuff<ElaborateStuff> 将是所有实例化的基类:
type ElaborateStuff = {
a: string
}
class SomeStuff<T extends ElaborateStuff> {
getVStuff(): T {
return null!;
}
}
function doSimpleThingsElaborateStuff(stuff: SomeStuff<ElaborateStuff>): void { }
doSimpleThingsElaborateStuff(new SomeStuff<{ a: "", }>()); //OK
doSimpleThingsElaborateStuff(new SomeStuff<{ a: "", b: "",}>()); // OK
function doSimpleThingsNever(stuff: SomeStuff<never>): void { }
doSimpleThingsNever(new SomeStuff<{ a: "", }>()); // Error
doSimpleThingsNever(new SomeStuff<{ a: "", b: "",}>()); // Error
Playground Link
如果你的类是逆变的,你可以使用never 并且SomeStuff 的任何实例化都将与它兼容,因为SomeStuff<never> 将是所有实例化的基类:
type ElaborateStuff = {
a: string
}
class SomeStuff<T extends ElaborateStuff> {
getStuff = (v: T): void => null!
}
function doSimpleThingsElaborateStuff(stuff: SomeStuff<ElaborateStuff>): void { }
doSimpleThingsElaborateStuff(new SomeStuff<{ a: "", }>()); // error
doSimpleThingsElaborateStuff(new SomeStuff<{ a: "", b: "",}>()); //error
function doSimpleThingsNever(stuff: SomeStuff<never>): void { }
doSimpleThingsNever(new SomeStuff<{ a: "", }>()); // ok
doSimpleThingsNever(new SomeStuff<{ a: "", b: "",}>());// ok
Playground Link
但是,如果您的类型是不变的,则只能使用any。 Lint 规则很有用,但可以忽略,any 也有很好的用例,例如本例。但是你应该知道这是类型不安全的,所以你不应该依赖编译器来检查任何涉及类型参数的操作:
type ElaborateStuff = {
a: string
}
class SomeStuff<T extends ElaborateStuff> {
getStuff = (v: T): T => {
v.a.big(); // error if a is not there
return v;
}
}
function doSimpleThingsElaborateStuff(stuff: SomeStuff<ElaborateStuff>): void { }
doSimpleThingsElaborateStuff(new SomeStuff<{ a: "", }>()); // error
doSimpleThingsElaborateStuff(new SomeStuff<{ a: "", b: "",}>()); //error
function doSimpleThingsNever(stuff: SomeStuff<never>): void { }
doSimpleThingsNever(new SomeStuff<{ a: "", }>()); // error
doSimpleThingsNever(new SomeStuff<{ a: "", b: "",}>());// error
function doSimpleThingsAny(stuff: SomeStuff<any>): void {
stuff.getStuff({}) // will trigger an error
stuff.getStuff({ a: ""}).foo // error on foo access
}
doSimpleThingsAny(new SomeStuff<{ a: "", }>()); // ok
doSimpleThingsAny(new SomeStuff<{ a: "", b: "",}>()); // ok
Playground Link