Reputation: 2250
I have a function in which a variable is declared with a reasonably complex structure:
export function foo() {
const myVar = {
// some properties with complex types here...
}
// Do something with `myVar`
}
And now I wish to export the type of myVar
so that I can use it in other files. Is there any way to get type information of scoped variables from outside the function? Something like this:
export type MyVarType = GetVariableFromFunction<typeof foo, "myVar">;
Some more context to avoid the XY problem:
I have created a TypedMessenger
class. The purpose of this class is to make it easier to communicate with iframes and workers etc. It works something like this:
import type {TheirHandlers} from "./worker.ts";
const myHandlers = {
foo(x: number) {
return x;
,
bar() {
return "hello";
},
};
export type MyHandlers = typeof myHandlers;
const messenger = new TypedMessenger<TheirHandlers, MyHandlers>();
messenger.setResponseHandlers(myHandlers);
On the other end you create a similar TypedMessenger
but with the two generic parameters flipped. And then you are able to call messenger.send("foo", 3)
and it will autocomplete and type check the arguments you passed in.
Now the issue that I'm running into is that I have created a messenger inside a function, and many of these handlers use variables from the scope of that function.
Upvotes: 3
Views: 1598
Reputation: 2250
Unfortunately getting types from outside the scope of a function is not possible right now. There's an open issue for it but it doesn't have any recent activity.
There's a couple of ways you can work around this though:
type MyVarType = {
x: boolean;
fn: (x: number) => void;
};
export function foo() {
const myVar = {
x: true,
fn: (x: number) => {}
}
}
The downside of this method is that you have to write your structure twice. First you have to declare the type, and then you have to create the value of the variable. If your variable is complex enough you might want to use one of the other methods.
myVar
outside of the function.const myVar = {
x: true,
fn: (x: number) => {}
}
export type MyVarType = typeof myVar;
export function foo() {
// Do stuff with `myVar`...
}
This works unless you need access to other variables inside your function:
const myVar = {
fn: (x: number) => {
console.log(scopedVar); // scopedVar doesn't exist :(
}
}
export type MyVarType = typeof myVar;
export function foo() {
const scopedVar = "hello";
myVar.fn(3);
}
ReturnType<...>
.function getMyVar(scopedVar: string) {
return {
fn: (x: number) => {
console.log(scopedVar);
}
}
}
export type MyVarType = ReturnType<typeof getMyVar>;
export function foo() {
const scopedVar = "";
getMyVar(scopedVar).fn(3);
}
As a last resort you can create a function that returns the variable, any scoped variables can be passed in the arguments of getMyVar
. And you can get the type of the variable using ReturnType<typeof getMyVar>
.
Upvotes: 2