I'm sure if this is possible, I'm beginner in TypeScript but what I'm trying to do is:
I have the following type;
type Special<C> = {
[Prop in keyof C]: C[Prop] extends Function | string ? C[Prop] : never;
}
There can only be properties of type string and Function, therefore, if there is a property of type number,Array, etc., it will produce an error:
class A {
public msg: string = 'Hello!';
public test() {}
}
const a: Special<A> = new A(); // Ok!
But:
class B {
public msg: string = 'Hello World!';
public Run() {}
public num: number = 123;
}
const b: Special<B> = new A(); // Error!, Type 'number' is not assignable to type 'never'.
If I try to do the same inside the body of a function, the type checking is not done:
type Class<ClassType = any, constructorParams = any> = {
new (...agrs: Array<constructorParams>): ClassType;
};
class A {
public msg: string = 'Hello!';
public test() {}
public num: number = 123;
}
const Testing = <T>(controller: Class<T>) => {
const a: Special<typeof controller> = new controller(); // is Ok!???
};
Testing(A); // is Ok!???
The only thing I was able to achieve was something like this to get the type checking to work:
class A {
public msg: string = 'Hello!';
public test() {}
public num: number = 123;
}
const Testing = <T>(controller: Class<Special<T>>) => {
const a = new controller();
};
Testing(A); // // Error!, Type 'number' is not assignable to type 'never'.
How can I achieve type checking of "Special " inside the body of the Testing function?
Am I doing something wrong? Am I not understanding something that is missing?
I hope you can help me :)
Based on your comment, it looks like you want the error to be raised in
testing's call site. That essentially means that you must constraint the type of the argumenttestingcan take in. And you should constrain it in a way so that the instance returned by a class constructor, is assignable toSpecial.Ok, the bearings you've already provided-
And here's the class that must not pass without error-
Here's a similar class that should pass without error-
Ok, now here's the description of your
testingfunction-Preliminary
It takes in a class constructor as its argument.
Declaration
Let
Tbe the type of the instance constructed by said class constructor.Constraint
Tmust be assignable toSpecial<T>Implementation
The way you constraint
Tto be assignable toSpecial<T>is by usingT extends Special<T>clause in your function. Combine everything from above, and you get-Nothing too special that hasn't already been discussed. I got rid of your
Classtype since I just wrote that type inline-new (...args: any[]) => T. Note theTthere. That's the instance type.Now you'll get an error on
testing(A)but not withtesting(B). The error you get is-Check it out on playground