-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to handle this when this is a function #22285
Comments
In your example you grab |
Ok so here is a jsfiddle of plain js and here is the code:
This will return the correct This is the code that makes
So back to the typescript example: it would be:
So is this too exotic for typescript to recognise or can I somehow indicate that the |
Basically, to allow you to implement it that way, there would have to be a mapped type that iterates over all methods and removes the // Assumes `T` is a type containing only function signatures.
class TypeClass<T> {
readonly symbol: symbol;
constructor(name: string) {
this.symbol = Symbol.for(name);
}
/**
* Must manually supply T<sometype> as the type argument because we don't have
* https://github.com/Microsoft/TypeScript/issues/1213
*/
instance<J extends T>(type: Function, implementation: J) {
type.prototype[this.symbol] = implementation;
}
// Unfortunately we need to pass in the keys here. Or you could try and get them from the first call to `instance`.
getImpls(keys: ReadonlyArray<keyof T>): T {
const out = {} as T;
for (const key of keys) {
out[key] = this.getImpl(key);
}
return out;
}
getImpl<K extends keyof T>(name: K): T[K] {
return ((left: any, ...args: any[]) => {
const impl = left[this.symbol] as T;
return (impl[name] as any)(left, ...args);
}) as any as T[K]
}
}
interface Add<T> {
add(left: T, right: T): T;
}
const adder = new TypeClass<Add<{}>>("Add");
adder.instance<Add<number>>(Number, {
add: (left, right) => left + right,
});
adder.instance<Add<string>>(String, {
add: (left, right) => left + right,
});
const { add } = adder.getImpls(["add"]);
console.log(add(1, 3));
console.log(add("1", "3")); |
This is really great but one thing, typescript does currently not support a symbol as an indexer: So the only way is to give the member
Or is there another way? |
If the symbol is dynamically created |
@Andy-MS this has been extremely helpful. I'm going to close the issue but is it possible to explain this commented line:
Why is it not just T that is the generic argument? |
|
@Andy-MS one problem with this is approach is that it expects the first argument to be the type argument, i.e.
but what if the type in question is not the first argument in question. Generic types do not exist at runtime in typescript as I've no idea what that would compile to. I guess I would need to pass something into the |
You won't be able to do something like have |
I have created this playground that shows the problem.
The code looks like this:
How do I handle
this
on line 44 of the playgroundlet { doSomething } = this(left);
the call to
this
will return the specificdoSomething
.At the moment I get the error, this lacks a callable signature.
If I add the false this param like this:
doSomething(this: (a: A) => Implementation<A>, left: A, right: A) {
And if I then export the function
export {doSomething} = Implementation.prototype;
And I then try to use the function:
doSomething({o: 1}, {b: 2});
I get the error:I realise this is quite contrived but is this too contrived for typescript?
The text was updated successfully, but these errors were encountered: