As @cartant suggested, you can use overloads in TypeScript. They have a single implementation but multiple signatures. You can read about it in the handbook to see how to make the signatures and implementation play well together. In your case, you can do something like this:
export class ConstantImpl<T> {
// guessing at your constructor
public constructor(public val: T) {
}
public static create(b: boolean): Constant<boolean>;
public static create(i: number): Constant<number>;
public static create(v: boolean | number): Constant<boolean | number> {
return new ConstantImpl(v);
}
}
This will only allow ConstantImpl.create() to accept a boolean or a number value, and it will reject everything else. Note that I didn't have to inspect the type of v to see if it is a boolean or a number, nor did I have to manually specify the value of T in the call to the ConstantImpl<T> constructor, because the constructor infers the value of T from the argument you pass in.
And really, in that case, it makes me wonder why you care to restrict ConstantImpl.create() to only accept boolean and number values. Why not go the full generic route instead?
// accept any type
public static create<T>(v: T): Constant<T> {
return new ConstantImpl(v);
}
Hope that helps; good luck.
BooleanandNumbertypes refer to objects created likenew Boolean(true)ornew Number(5), not to the primitivebooleanandnumbervalues liketrueand5. If it is not really your intention to deal with such unusual non-primitives, you should change tobooleanandnumberinstead.