Estoy codificando una clase ReactJS con Typescript y Material-ui, en un archivo .tsx. En uno de mis componentes personalizados, quiero crear una referencia a uno de los componentes que uso en mi componente personalizado.
export class MyTextField extends React.Component<MyProps, MyState> { private refTextField: React.RefObject<TextField>; constructor(props: MyProps) { super(props); this.refTextField = React.createRef(); } render(): JSX.Element { const { id, label, value: defaultValue } = this.props; const { value } = this.state; const element = ( <TextField ref={this.refTextField} id={id} label={label} defaultValue={defaultValue} value={value} /> ); return element; } }Durante la compilación, aparece un error en la declaración de mi referencia:
'TextField' se refiere a un valor, pero aquí se usa como un tipo. TS2749
Traté de poner "typeof TextField" en mi declaración, pero tengo otro mensaje, al valorar la propiedad ref en mi renderizado:
El tipo 'RefObject<(props: TextFieldProps) => Element>' no se puede asignar al tipo '((instancia: HTMLDivElement | null) => void) | RefObjeto | nulo | indefinido'. El tipo 'RefObject<(props: TextFieldProps) => Element>' no se puede asignar al tipo 'RefObject'. Al tipo '(props: TextFieldProps) => Element' le faltan las siguientes propiedades del tipo 'HTMLDivElement': align, addEventListener, removeEventListener, accessKey y 238 más. TS2322
Algunas ideas ? Muchas gracias
Asegúrese de estar en un archivo .tsx y no en un archivo .ts
Así que me encontré con este problema varias veces en mi código antes, pero solo descubrí la razón por la que esto estaba sucediendo hoy.
TL; DR al final para la respuesta real a la pregunta.
Cuando crea una clase en TypeScript, el nombre de esa clase se refiere tanto al tipo de instancia como al valor de la clase de Javascript. Si hace referencia a esa clase como un tipo, TypeScript lo detecta automáticamente como el tipo de instancia de esa clase. Y si hace referencia a esa clase en el tiempo de ejecución, simplemente la usa como en el significado de Javascript. Y todo es bueno y elegante hasta ahora.
class MyClass {} let abc: MyClass; // ts recognizes as instance type abc = new MyClass(); // completely fine, used here as the javascript valueSin embargo, el verdadero problema es cuando exportas la clase desde un módulo dinámicamente . Cuando exporta la clase de alguna manera, TypeScript solo puede exportar el valor de Javascript de la clase y no exporta el tipo. Entonces, si lo importa en otro módulo e intenta hacer referencia a él como un tipo, obtendrá TS2749.
let intervariable = class MyClass{} export const MyClass = intervariable; // TypeScript does not export type here. import {MyClass} from './myclass'; let abc: MyClass; // TypeScript error TS2749Cuando esto sucede, especialmente si está fuera de su control, mi solución para obtener el tipo de instancia fue simplemente usar InstanceType y typeof:
import {MyClass} from './myclass'; let abc: InstanceType<typeof MyClass>; // no error // the rest...El operador typeof le proporciona el tipo de constructor de clase para un valor de clase, y el tipo de instancia genérico le proporciona el tipo de instancia que desea.
TL;DR: En su caso, solo tiene que escribir InstanceType<typeof TextField> en lugar de TextField .
Para futuros espectadores, el error también puede deberse a que no importó la clase en primer lugar.
cambie el archivo .ts a .tsx
Esto debería haber sido un comentario, pero no tengo suficiente reputación. Quería compartir que una forma limpia de usar la solución recomendada por la respuesta aceptada es declarar un alias de tipo con el mismo nombre ( no causa conflicto ). Luego puede usar su tipo de la misma manera que normalmente usaría un tipo de instancia.
Agregando al ejemplo:
import {MyClass} from './myclass'; type MyClass = InstanceType<typeof MyClass>; let abc: MyClass; // still no error!Editar: una importación de tipo parece funcionar también y se ve más limpia:
import type {MyClass} from './myclass'; La advertencia con el enfoque de import type es que no puede usarlo como un valor (por ejemplo, construir una new MyClass(...) ).
Tuve que cambiar heroes: HEROES a heroes = HEROES .
Me encontré con esta misma x refers to a value, but is being used as a type here. Did you mean 'typeof x'? error al construir una aplicación Angular. Pasé dos horas buscando la solución, leyendo esta publicación de Stack Overflow varias veces. Simple error de mi parte.
Otra cosa que debe verificar es si la importación que está realizando está rodeada por {} . Una de las razones por las que aparece este mensaje es porque cualquier cosa que no esté rodeada por {} se trata como la exportación predeterminada de un archivo.