score:59

Accepted answer

So I ran into this problem multiple times in my code before but only figured out the reason this was happening today.

TL;DR at the end for the actual answer to the question.

When you create a class in TypeScript, the name of that class refers to both the instance type and the Javascript class value. If you reference that class as a type, TypeScript detects that automatically as the instance type of that class. And if you reference that class in the runtime, it just uses it as in the Javascript meaning. And it's all good and dandy till now.

class MyClass {}
let abc: MyClass; // ts recognizes as instance type
abc = new MyClass(); // completely fine, used here as the javascript value

However, the real problem is when you export the class from a module dynamically. When you export the class in some ways, TypeScript can only export the Javascript value of the class and does not export the type. So if you import it in another module and try to reference it as a type, you will get TS2749.

let intervariable = class MyClass{}
export const MyClass = intervariable; // TypeScript does not export type here.
import {MyClass} from './myclass';

let abc: MyClass; // TypeScript error TS2749

When this happens, especially if it is out of your control, my solution to get the instance type was simply to use InstanceType and typeof:

import {MyClass} from './myclass';

let abc: InstanceType<typeof MyClass>; // no error
// the rest...

The typeof operator gets you the class constructor type for a class value, and the InstanceType generic gets you the instance type that you want.

TL;DR: In your case you just have to write InstanceType<typeof TextField> instead of TextField.

score:0

For future viewers, the error might also be caused by you not importing the class in the first place.

score:0

I had to change heroes: HEROES to heroes = HEROES.

I ran across this same x refers to a value, but is being used as a type here. Did you mean 'typeof x'? error building an Angular app. I spent two hours searching for the fix, reading this Stack Overflow post several times. Simple mistake on my part.

score:1

Another thing to check is if the import you're performing is surrounded by {} . One of the reasons this message appears is because anything that is not surrounded by {} is treated as the default export for a file.

score:8

This should have been a comment, but I don't have enough reputation. I wanted to share that a clean way to use the solution recommended by the accepted answer is to declare a type alias with the same name (it does not cause a conflict). Then you can use your type in the same way you would normally use an instance type.

Adding to the example:

import {MyClass} from './myclass';

type MyClass = InstanceType<typeof MyClass>;

let abc: MyClass; // still no error!

Edit: A type import seems to work as well and it looks cleaner:

import type {MyClass} from './myclass';

The caveat with the import type approach is that you cannot use it as a value (e.g. constructing new MyClass(...)).

score:139

change .ts file to .tsx

in my case it works

score:388

Make sure you're on a .tsx file and not a .ts file


Related Query

More Query from same tag