Dans un article précédent je rendais compte d’un étude menée scientifiquement pour évaluer l’aide que pourrait apporter, ou pas, l’IA au travail de 16 développeurs expérimentés pour résoudre 246 problèmes de maintenance relatifs aux projets dont ils étaient familiers depuis des années : la conclusion était que l’IA leur faisait plutôt perdre du temps.
Ici je vais décrire de façon beaucoup plus empirique mon expérience avec l’IA (ChatGPT en l’occurrence) pour m’initier à un langage de programmation avec lequel je débute, TypeScript. TypeScript est une couche objet ajoutée à JavaScript par des ingénieurs de Microsoft (sous la direction d’Anders Hejlsberg) pour en rendre la programmation plus robuste et plus lisible (ce sont des euphémismes). Soyez charitables pour les faiblesses que j’exhibe ! En tout cas ChatGPT m’a bien aidé : c’est comme travailler sous les yeux d’un collègue plus expérimenté qui aperçoit tout de suite les erreurs grossières de débutant.
Première question
// Bonsoir ChatGPT,
// Voici, ci-dessous, un code TypeScript correct, constitué de deux classes et d’un certain nombre de méthodes. Peux-tu répartir les classes et les méthodes dans autant de NameSpaces, puis placer chaque NameSpace dans un fichier, tels que le compilateur tsc puisse assembler le code et le soumettre à la machine JavaScript ?
const uneListePersonnages = new ListeSimple
uneListePersonnages.prepend("Tintin") ;
uneListePersonnages.prepend("Haddock") ;
uneListePersonnages.prepend("Milou") ;
console.log(uneListePersonnages.traverse()) ;
Réponse :
Parfait 👍 Ton code est bien structuré. Pour répondre à ta demande, je vais te montrer comment répartir les classes dans des namespaces, puis les mettre chacune dans un fichier séparé afin que tsc puisse assembler le tout correctement.
1. Organisation proposée
On va séparer en deux fichiers principaux :
N.ts → contient le namespace NodeSpace avec la classe N
ListeSimple.ts → contient le namespace ListeSpace avec la classe ListeSimple (qui dépend de N)
Enfin, on aura un fichier main.ts pour tester l’ensemble.
2. Fichier : N.ts
3. Fichier : ListeSimple.ts
4. Fichier : main.ts
5. Compilation avec tsc
Exécute :
tsc —outFile dist/app.js main.ts
⚡ Ici on utilise —outFile car on travaille avec des namespaces (et pas avec des modules ES6 import/export). Le compilateur va assembler N.ts, ListeSimple.ts et main.ts dans un seul fichier dist/app.js exploitable en JavaScript.
👉 Veux-tu que je te propose aussi une version avec modules ES6 (export / import), plus moderne que les namespace + ///
Oui.
Seconde réponse, meilleure :
ChatGPT a dit :
Parfait 👌 allons-y avec la version moderne en modules ES6.
Ici, pas de namespace ni de ///
1. Fichier N.ts
2. Fichier ListeSimple.ts
3. Fichier main.ts
4. Compilation avec tsc
Crée un tsconfig.json (si tu n’en as pas déjà un) :
Ensuite, compile :
tsc
Cela va générer dans dist/ :
N.js
ListeSimple.js
main.js
👉 Petite différence d’usage :
Avec namespaces, on regroupe tout en un seul fichier avec —outFile.
Avec modules ES6, chaque fichier génère son propre .js, et on les relie via import / export.
Suite de la question :
Bonjour ChatGPT, j’ai créé en TypeScript une classe de liste associative :
Bonjour ! Veux-tu me montrer le code de ta classe TypeScript de liste associative ? Comme ça je pourrai t’aider à l’améliorer, la corriger, ou l’adapter selon ton besoin.
Suite de la question :
Vous avez dit (je vouvoie encore ChatGPT)
:
En fait on n’a besoin que de prepend. Et je crée un tableau de listes pour créer une table de hash, ainsi :
Réponse :
ChatGPT a dit :
Merci pour le partage ! 🙂
Là tu as deux morceaux : une liste associative chaînée (ListeAssoc) et une table de hachage (HashTable). Je vois quelques points qui risquent de poser problème dans ton code actuel :
1. La déclaration de HashTable
export class HashTable
Ici tu appelles ton paramètre générique ListeAssoc, mais ce nom est déjà pris par ta classe importée ListeAssoc. En fait, tu veux plutôt paramétrer les types clé et valeur, pas redéclarer une classe.
👉 Je te propose de renommer les génériques en Tkey, Tvalue et éventuellement N pour la taille.
2. La construction de aTable
public aTable : Tuple
Ici, tu veux un tableau de listes associatives. Or Tuple
3. Ton init
Problème : tu réutilises la même instance de ListeAssoc pour toutes les cases. Résultat : tout ton tableau pointe vers une seule liste partagée.
Il faut recréer une nouvelle ListeAssoc à chaque itération.
Version corrigée
👉 Ici :
HashTable prend des types génériques clé et valeur (Tkey, Tvalue).
On construit un tableau de ListeAssoc indépendantes.
J’ai ajouté une fonction de hachage simple + des méthodes set et get pour illustrer.
Troisième question :
Re-bonjour,
Voilà, j’ai déclaré une classe HashTable selon tes conseils :
Je crée une instance :
const myHashTable = new HashTable(6) ;
J’inscris des personnages dans la table :
myHashTable.set("Tournesol", 18) ;
myHashTable.set("Dupont", 19) ;
Quand j’interroge j’ai la bonne réponse :
console.log("Dupont : ", myHashTable.get("Dupont")) ;
– > Dupont : 19
Mais si j’écris :
Je n’ai pas de réponse, et si j’écris :
on me dit :
Qu’est-ce qui ne va pas ?
Réponse :
Je vois tout de suite où ça coince 👍
Dans ta boucle tu fais :
👉 problème :
myHashTable est un objet de type HashTable, pas un tableau.
L’attribut qui contient tes listes est aTable, donc tu dois accéder à myHashTable.aTable[pas].
Ensuite, chaque case de aTable est une ListeAssoc, qui a un champ head pointant vers le premier Nassoc.
En gros, myHashTable[pas] n’existe pas → ça vaut undefined.
✅ Correction
Pour parcourir toutes les cases et tous les nœuds, fais comme ceci :
Autres points :
Dans ton constructeur, il manque des () à l’appel du constructeur ListeAssoc :
this.aTable[i] = new ListeAssoc
(sinon tu construis une référence vers la classe, pas une instance).
current.ListeAssoc.traverse n’a aucun sens :
current est un Nassoc, il a seulement key, value et next.
Si tu veux faire une méthode traverse, elle doit être définie dans ListeAssoc (et tu l’appellerais avec myHashTable.aTable[pas].traverse()).