1

I am trying to set the type of a variable to a property of an object, such as in the code below.

class Foo {

}

const obj = {
  Foo,
};

const foo: Foo; // valid
const bar: obj.Foo; // Cannot find namespace 'obj'.

This gives me the error Cannot find namespace 'obj'. Is there a way of setting the type of a variable from an object property, such that foo and bar are of type Foo?

3 Answers 3

2

First you need to get the type of the obj (using typeof), then you can query its Foo property type:

declare const bar: (typeof obj)["Foo"];

Pay attention bar is constructor, not an instance.

If you're looking for instance type, you can use InstanceType utility:

declare const bar: InstanceType<(typeof obj)["Foo"]>;

If you need something more reusable:

type Obj = typeof obj;
type GetType<K extends keyof Obj> = InstanceType<Obj[K]>

const bar: GetType<'Foo'> = new obj.Foo();
Sign up to request clarification or add additional context in comments.

2 Comments

That could also work, but declaring const bar: obj.Foo (as I think the user expects it) would be declare const bar: InstanceType<(typeof obj)["Foo"]> a bit of a mouthful ..
Thanks, just was also adding InstanceType part
2

There is no way to add a type to an object type. The closest thing you can do is use a namespace definition. A namespace can have both variables and types. A namespace is represented as an object at runtime so it might be close enough to what you need:

class Foo {

}
type _Foo = Foo;
const _Foo = Foo;
namespace obj {
    export type Foo = _Foo;
    export const Foo = _Foo; // to allow instantiation through obj.Foo
};

const foo: Foo; // valid
const bar: obj.Foo = new obj.Foo()

2 Comments

This works, but is there any way of decreasing the size of this? I'm dealing with 90~ classes
@SebastiaanYN Problem is you are using the same name, so the external name will be aliased, hence the need for the external _ definitions. Also you need to export both the type and the value (const) to make a class work exactly as before .. not sure how I would reduce it given these constraints ..
0

You can assign the type it in a compact way like this let bar: {Foo}

Update

Also since I mentioned obj is not a namespace so I tried the typeof keyword since we want the type of that property. so you can try it out like this

let bar: typeof obj.Foo;

6 Comments

This doesn't answer my question. That simply says that bar is an object with a property Foo of type any.
@SebastiaanYN Since obj is NOT a namespace (i.e a class or an Interface) It would be impossible to set the Type to an object's Property. Also because the obj.value syntax get's the value of the property not its type
@SebastiaanYN I have updated the answer. Please check it out now
const bar: typeof obj.Foo = new obj.Foo(); would give Property 'prototype' is missing in type 'Foo' but required in type 'typeof Foo'.
@SebastiaanYN I am also getting the error in TS but if you run the code and see the console It does create the Foo object and with no error in the browser (Strange)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.