6

Mon équipe travaille sur un projet NodeJS relativement volumineux, écrit en ES6, transpilé par babel, puis déployé comme AWS lambdas avec Serverless. Ce projet est axé sur la consommation, la cartographie/transformation et la sortie d'un type d'objet spécifique, que nous avons défini. Notre problème est que ECMA/JavaScript n'est pas fortement typé, donc si nous faisons une erreur en traitant un champ comme un tableau quelque part et une chaîne ailleurs, il n'y a rien d'autre à faire que des erreurs d'exécution. Nous avons également mal documenté la structure de cet objet, donc parfois les consommateurs nous envoient des instances de l'objet avec des données dans des champs légèrement mal nommés que nous disons traiter, mais que nous n'utilisons pas réellement. Je cherche un moyen de créer une sorte de schéma ou de définition de type pour cet objet spécifique dans notre projet, afin que nous puissions l'utiliser pour corriger notre code, rendre notre traitement plus robuste, et créer une bien meilleure documentation pour cela . Maintenant, je sais que VSCode offre quelques basic type checking en JavaScript, mais je ne pense pas qu'il soit possible d'essayer JSDoc un très gros objet et ensuite mettre ce doc dans chaque fichier qui utilise l'objet. J'ai trouvé que VSCode peut aussi, en quelque sorte, conduire cette vérification with .d.ts files mais je ne comprends pas si ou comment je peux tirer parti de cela pour un objet spécifique, personnalisé que nous avons conçu. La plupart de ce que j'ai trouvé semble être spécifiquement lié à l'extraction de fichiers .d.ts pour des bibliothèques externes. Donc, TL: DR, est-il possible, dans un projet NodeJS/ES6, de faire un objet, largement utilisé dans ce projet, fortement typé? Une vérification d'erreur dans VSCode serait acceptable, mais une sorte de lissage de ligne de commande que nous pourrions déclencher avant de passer serait également très bien.Est-il possible d'utiliser des définitions de type personnalisées dans un projet ES6?

+2

En JavaScript, non. Convertissez tout en TypeScript, puis * peut-être *, bien que vous ne puissiez pas faire grand-chose à propos du code externe passant un objet munged à votre API autre que de le valider explicitement. – Pointy

+3

Votre problème est exactement pourquoi existe-t-il des caractères dactylographiés. Vous pouvez écrire votre "un objet" en tapuscrit et utiliser cet objet dans d'autres fichiers javascript. Est-ce que tapuscrit émet un fichier de déclaration avec l'option [compilateur '--declaration'] (https://www.typescriptlang.org/docs/handbook/compiler-options.html) et je pense que quand vous" require "le js compilé, vscode va détecter les typages. Il existe également une option de compilation permettant à ['checkJS' d'émettre des erreurs de type pour les fichiers javascript] (https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-3.html#errors-in- js-files-with-checkjs). –

+0

[Cela devrait aider un peu aussi.] (Https://github.com/Microsoft/TypeScript/wiki/Type-Checking-JavaScript-Files) –

Répondre

3

Très bien, compris. Après avoir posté cette question, j'ai continué à googler et après environ une heure, j'ai lu cet article sur StrongLoop par Sequoia McDowell: https://strongloop.com/strongblog/type-hinting-in-javascript/

Je l'ai suivi de très près et, en utilisant le paquet "typings", j'ai pu initialiser un " "typings" dossier à la racine de mon projet. Le contenu de ce dossier ressemble maintenant à ceci:

typings/ 
├── models/ 
│ └── myObject.d.ts 
└── index.d.ts 

Le contenu de ce regard de fichier index.d.ts comme ceci:

/// <reference path="models/myObject.d.ts" /> 

Et le contenu de ce look fichier myObject.d.ts quelque chose de vaguement comme ceci:

declare namespace MyProject { 
    export interface MyObject { 
    aString?: string; 
    anotherString?: string; 
    aComplexType?: ComplexType; 
    } 

    interface ComplexType { 
    aString?: string; 
    anotherComplexType: SecondComplexType; 
    } 

    interface SecondComplexType { 
    aString?: string; 
    } 
} 

cela fait, je devais commencer à marquer des instances de cet objet avec JSDoc. Ce document principalement a deux formes:

Avec cette configuration
/** 
* Creates an instance of UtilityThing. 
* @param {MyProject.MyObject} myObject 
* 
* @memberof UtilityThing 
*/ 
constructor(myObject) { 
    this.myObject = myObject; 
} 

/** 
* @param {MyProject.MyObject} myObject 
* @returns {MyProject.MyObject} 
*/ 
function noOp(myObject) { 
    return myObject; 
} 

et

/** @type {MyProject.MyObject} */ 
const myObject = containerObject.myObject; 

, et la dernière version publique de VSCode, j'ai pu voir des erreurs dans les fichiers de ES6 * que j'étais actuellement édition qui m'a dit quels attributs n'existaient pas, auxquels on attribuait des valeurs du mauvais type, qui étaient supposées être du mauvais type, etc.

À mi-chemin.Après quelques recherches supplémentaires, j'ai compris que ce n'est pas exactement une caractéristique VSCode unique. Il semble qu'ils utilisent "tslint" ou une version personnalisée de celui-ci. Travailler avec cette connaissance, j'ai ajouté « tslint » au projet et a travaillé ce script NPM:

"tslint": "tslint --type-check --project tsconfig.json" 

Voici le contenu du tsconfig.json que je suis tombé sur, mais je ne suis pas tout à fait sûr tous ces options sont nécessaires.

{ 
    "compilerOptions": { 
    "target": "es6", 
    "allowJs": true, 
    "noResolve": true, 
    "checkJs": true, 
    "moduleResolution": "node", 
    "types": [ 
     "node" 
    ] 
    }, 
    "exclude": [ 
    "node_modules", 
    "coverage", 
    "lib", 
    "spec" 
    ] 
} 

L'exécution de ce script « tslint », avec ce tsconfig.json, et les fichiers de définition de type dans le dossier « typages » me permet de taper vérifier un type d'objet spécifique dans tous les fichiers du projet avec JSDoc approprié. Je suis tombé sur un small issue mais cela semble avoir été corrigé et fusionné il y a environ une heure, par coïncidence. En plus de vérifier les champs de l'objet, cela a également révélé un couple d'endroits où un attribut était tiré prématurément d'un objet dont le descendant avait cet attribut. Très sympa.

TL; DR: Cela peut être fait, énorme grâce à Sequoia McDowell pour cet article qui m'a finalement mis sur la bonne voie.