问题
I'd like to have something like this:
SomeAbsClass.getSomething<IMyType>("IMyType");
So, how to I code getSomething
's parameter so it'll only accept the exact "IMyType" as string?
There's something to do with Conditional types, in the same vein as this, but I can't figure it out.
回答1:
There's no inherent relationship in TypeScript between string literal types (like "IMyType"
) and the names of named types (like IMyType
). String literal types represent actual string values which exist at runtime, while type names respresent aspects of the static type system which is completely erased from the emitted JavaScript.
Furthermore, the type system is structural, not nominal, so the names of types don't really matter much. If I declare
type IYourType = IMyType;
then IYourType
and IMyType
are just two different names for the same type. And therefore if SomeAbsClass.getSomething<IYourType>("IYourType");
succeeds, then SomeAbsClass.getSomething<IMyType>("IYourType");
should also succeed.
There's no principled way to force the type system to decide that one name is more "canonical" than another, so that SomeAbsClass.getSomething<IMyType>("IMyType");
succeeds and SomeAbsClass.getSomething<IMyType>("IYourType");
fails automatically.
Since this doesn't happen automatically, the closest I can imagine getting here is for you to manually build up a type representing the desired mapping between string literals and types, such as:
interface TypeMapping {
IMyType: IMyType;
Date: Date;
string: string;
boolean: boolean;
// add whatever you want
}
and then use that mapping in your definition of getSomething()
, like this
declare const SomeAbsClass: {
getSomething<T>(x: {
[K in keyof TypeMapping]: TypeMapping[K] extends T ? K : never }[keyof TypeMapping]
): void;
}
And you call it like this (making sure to explicitly specify the generic type parameter when you do so):
SomeAbsClass.getSomething<IMyType>("IMyType"); // okay
SomeAbsClass.getSomething<IMyType>("IYourType"); // error
That works as far as it goes. Whether it fits your use case is another story.
Okay, hope that helps; good luck!
Playground link to code
来源:https://stackoverflow.com/questions/60973387/tell-methods-parameter-to-accept-only-t-as-exact-string