Hoy estaba escribiendo un archivo de declaración de tipo para un archivo JavaScript pero, a pesar de mis horas de intento, no pude hacerlo funcionar dentro de una aplicación de nodo. Luego intenté cambiar a la sintaxis del módulo es6 y, sorprendentemente, funcionó.
Luego descubrí que también puedo hacer que funcione con la sintaxis del módulo commonjs si agrego ".default" antes de acceder a cualquier propiedad de ese módulo. Por ejemplo, tengo que usar person.default.name en lugar de person.name para obtener la inteligencia.
Escribí un pequeño módulo para demostrar el problema. Creé un objeto con tipos idénticos de mi módulo real.
índice.js
const names = { firstname: "Alex", middlename: "Blex", lastname: "Clex", }; const state = { isAlive() { return true; }, isWalking() { return false; }, }; function talk(speech) { console.log(speech); } const person = { names, state, talk }; module.exports = person;índice.d.ts
declare type predicate = (v: unknown) => boolean; declare function talk(speech: string): void; declare const person: { names: { [key: string]: string; }; state: { [key: string]: predicate; }; talk: typeof talk; }; export default person;prueba1.js
const person = require("./index"); const isAlive = person.default.state.isAlive(); //---------------------^^^^^^^---------------- // The above line throws an error as expected. // I've to use "person.default.whatever" to get intellisence // In the editor it shows "typeof isAlive = boolean". const isReallyAlive = person.state.isAlive(); // EditorError: Property 'state' does not exist on type // 'typeof import(./index.js)'. // In the editor it shows typeof "isReallyAlive = any" // But infact isReallyAlive is boolean.prueba2.js
Usando la sintaxis del módulo es6 funciona perfectamente.
Soy bastante nuevo en Typescript, así que amablemente dame alguna pista sobre dónde estoy cometiendo el error. Gracias de antemano, aprecio mucho su tiempo en StackOverflow <3.
Entonces, como se explica en esta publicación https://stackoverflow.com/a/40295288/10315665 , la opción export default solo crea una clave default dentro del objeto de exports . Es por eso que aún puede tener exportaciones normales además de eso.
Mucha gente considera que module.exports = ... es equivalente a export default ... y que export.foo ... es equivalente a export const foo = ... Sin embargo, eso no es del todo cierto, o al menos no cómo Babel lo hace.
Entonces su archivo de definición es incorrecto. Debería ser:
declare type predicate = (v: unknown) => boolean; export declare const names: { [key: string]: string; }; export declare const state: { [key: string]: predicate; }; export declare function talk(speech: string): void;Y si respeta eso, puede utilizar mecanografiado y es una verificación de tipos increíble simplemente escribiendo mecanografiado en primer lugar:
export const names = { firstname: "Alex", middlename: "Blex", lastname: "Clex", }; export const state = { isAlive() { return true; }, isWalking() { return false; }, }; export function talk(speech: string) { console.log(speech); } Solo recuerde habilitar "declaration": true en tsconfig para generar también archivos de declaración 😉.