Le référentiel pour les définitions de types TypeScript de haute qualité .
Vous pouvez également lire ce README en espagnol, 한국어, Русский, 简体中文, Português, Italiano, 日本語 et Français !
Lien vers le manuel d'administration
Definitely Typed a récemment été remplacé par un monorepo pnpm
approprié ; vous souhaiterez peut-être relire ce document pour connaître les modifications apportées à la disposition des packages dans ce dépôt.
À tout le moins, vous souhaiterez peut-être git clean -fdx
le dépôt (ou node ./scripts/clean-node-modules.js
sous Windows) pour nettoyer node_modules
et exécuter pnpm install --filter .
pour installer la racine de l'espace de travail. Voir les sections suivantes pour plus d'informations sur pnpm install
.
Cette section suit la santé du référentiel et du processus de publication. Cela peut être utile pour les contributeurs rencontrant des problèmes avec leurs PR et leurs packages.
Si quelque chose ici semble faux ou si l'un des éléments ci-dessus échoue, veuillez nous le faire savoir sur le canal Definitely Typed sur le serveur Discord de la communauté TypeScript.
Consultez le manuel TypeScript.
C'est la méthode préférée. Par exemple:
npm install --save-dev @types/node
Pour installer des saisies pour un module étendu, supprimez le @
et ajoutez un double trait de soulignement après la portée. Par exemple, pour installer les typages pour @babel/preset-env
:
npm install --save-dev @types/babel__preset-env
Les types devraient alors être automatiquement inclus par le compilateur. Vous devrez peut-être ajouter une référence types
si vous n'utilisez pas de modules :
/// <reference types="node" />
Voir plus dans le manuel.
Pour un package npm "foo", la saisie se fera à "@types/foo".
Si votre package a des typages spécifiés à l'aide de la clé types
ou typings
dans son package.json
, le registre npm affichera que le package a des liaisons disponibles comme ceci :
Vous pouvez cloner l'intégralité du référentiel comme d'habitude, mais il est volumineux et comprend un énorme répertoire de packages de types. Cela prendra un certain temps à cloner et peut être inutilement lourd.
Pour un clone plus gérable qui inclut uniquement les packages de types qui vous concernent, vous pouvez utiliser les fonctionnalités sparse-checkout
et --filter
de git. Cela réduira le temps de clonage et améliorera les performances de Git.
️ Cela nécessite au minimum la version 2.27.0 de Git, qui est probablement plus récente que la version par défaut sur la plupart des machines. Des procédures plus compliquées sont disponibles dans les anciennes versions, mais ne sont pas couvertes par ce guide.
git clone --sparse --filter=blob:none <forkedUrl>
--sparse
initialise le fichier sparse-checkout afin que le répertoire de travail démarre uniquement avec les fichiers à la racine du référentiel.--filter=blob:none
inclura tout l'historique des validations mais exclura les fichiers, en les récupérant uniquement si nécessaire.git sparse-checkout add types/<type> types/<dependency-type> ...
pnpm test <package to test>
. Lorsque vous effectuez un PR pour modifier un package existant, dt-bot
doit @-mentionner les propriétaires du package. Si ce n'est pas le cas, vous pouvez le faire vous-même dans le commentaire associé au PR.
Si vous êtes l'auteur de la bibliothèque et que votre package est écrit en TypeScript, regroupez les fichiers de déclaration générés dans votre package au lieu de publier sur Definitely Typed. Vous pouvez également générer des fichiers de déclaration à partir de fichiers JavaScript, en utilisant JSDoc pour les annotations de type.
Si vous ajoutez des typages pour un package npm, créez un répertoire avec le même nom. Si le package pour lequel vous ajoutez des saisies n'est pas sur npm, assurez-vous que le nom que vous choisissez n'est pas en conflit avec le nom d'un package sur npm. (Vous pouvez utiliser npm info <my-package>
pour vérifier l'existence du package <my-package>
.)
Votre package doit avoir cette structure :
Déposer | But |
---|---|
index.d.ts | Celui-ci contient les saisies du package. |
<my-package>-tests.ts | Celui-ci contient un exemple de code qui teste les saisies. Ce code ne s'exécute pas , mais il est vérifié. |
tsconfig.json | Cela vous permet d'exécuter tsc dans le package. |
.eslintrc.json | (Rarement) Nécessaire uniquement pour désactiver les règles de charpie écrites pour eslint. |
package.json | Contient les métadonnées du package, notamment son nom, sa version et ses dépendances. |
.npmignore | Spécifie quels fichiers sont destinés à être inclus dans le package. |
Générez-les en exécutant npx dts-gen --dt --name <my-package> --template module
. Voir toutes les options sur dts-gen.
Si vous avez des fichiers .d.ts
en plus de index.d.ts
, assurez-vous qu'ils sont référencés soit dans index.d.ts
, soit dans les tests.
Les membres de Definitely Typed surveillent régulièrement les nouveaux PR, mais gardez à l'esprit que le nombre d'autres PR peut ralentir les choses.
Pour un bon exemple de package, voir base64-js.
Lorsqu'un package regroupe ses propres types, les types doivent être supprimés de Definitely Typed pour éviter toute confusion.
Vous pouvez le supprimer en exécutant pnpm run not-needed <typingsPackageName> <asOfVersion> [<libraryName>]
.
<typingsPackageName>
: C'est le nom du répertoire à supprimer.<asOfVersion>
: Un stub sera publié sur @types/<typingsPackageName>
avec cette version. Doit être supérieur à toute version actuellement publiée et doit être une version de <libraryName>
sur npm.<libraryName>
: Nom du package npm qui remplace les types Definitely Typed. Habituellement, cela est identique à <typingsPackageName>
, auquel cas vous pouvez l'omettre. Si un package n’a jamais été sur Definitely Typed, il n’est pas nécessaire de l’ajouter à notNeededPackages.json
.
Testez vos modifications en exécutant pnpm test <package to test>
où <package to test>
est le nom de votre package. Vous devez l'exécuter à partir du répertoire DefinitelyTyped car les package.jsons individuels ne définissent pas de scripts de test.
Ce script utilise dtslint pour exécuter le compilateur TypeScript sur vos fichiers dts.
Une fois que toutes vos modifications sont prêtes, utilisez pnpm run test-all
pour voir comment vos modifications affectent les autres modules.
attw
) vérifie dtslint inclut les vérifications du format de module et de la configuration package.json
de @arethetypeswrong/cli. Les vérifications ne s'exécutent que si un package d'implémentation compatible SemVer-major peut être trouvé sur npm pour le comparer au package DefinitelyTyped. (Les packages DefinitelyTyped marqués comme nonNpm
dans leur package.json
sont ignorés.)
De nombreux packages échouent actuellement aux vérifications attw
et doivent être corrigés. Pour nous permettre de faire des progrès incrémentiels, les vérifications attw
échouées n'échouent pas l'exécution dtslint
lorsque le package est répertorié dans failingPackages
dans attw.json
, mais ils seront toujours signalés dans la sortie pnpm test my-package
. Si vous corrigez le package, supprimez-le de failingPackages
afin que les vérifications attw
puissent commencer à échouer aux exécutions dtslint
.
Tous les problèmes signalés par attw
ont une documentation liée dans la sortie. Quelques règles empiriques pour éviter les problèmes :
Le package.json
dans le package DefinitelyTyped doit avoir des champs type
et exports
correspondants si le package d'implémentation les utilise dans son package.json
. Par exemple, si un package.json
d’implémentation ressemble à :
{
"name" : " my-package " ,
"version" : " 1.0.1 " ,
"type" : " module " ,
"main" : " dist/cjs/index.cjs " ,
"exports" : {
"." : {
"import" : " ./dist/esm/index.js " ,
"require" : " ./dist/cjs/index.cjs "
},
"./subpath" : {
"import" : " ./dist/esm/subpath.js " ,
"require" : " ./dist/cjs/subpath.cjs "
}
}
}
alors le package.json
DefinitelyTyped devrait ressembler à quelque chose comme :
{
"name" : "@types/my-package" ,
"version" : "1.0.9999" ,
"type" : "module" ,
"types" : "index.d.ts" ,
"exports" : {
"." : {
"import" : "./index.d.ts" ,
"require" : "./index.d.cts"
} ,
"./subpath" : {
"import" : "./subpath.d.ts" ,
"require" : "./subpath.d.cts"
}
}
}
Notez que chaque sous-chemin exports
est reflété et que chaque fichier JavaScript a un fichier de déclaration correspondant avec une extension de fichier correspondante : un fichier .d.ts
type un fichier .js
, pas un fichier .mjs
ou .cjs
!
Lorsque le package d'implémentation utilise module.exports = ...
, le package DefinitelyTyped doit utiliser export =
, et non export default
. (Alternativement, si module.exports
est simplement un objet de propriétés nommées, le package DefinitelyTyped peut utiliser une série d'exportations nommées.) L'obstacle le plus courant à la correction de ce problème est la confusion sur la manière d'exporter des types en plus de l'exportation principale. Par exemple, supposons que ces types utilisent incorrectement export default
:
export interface Options {
// ...
}
export default function doSomething ( options : Options ) : void ;
Changer la export default
en export =
crée une erreur :
export interface Options {
// ...
}
declare function doSomething ( options : Options ) : void ;
export = doSomething ;
// ^^^^^^^^^^^^^^^^^
// Error: An export assignment cannot be used in a module with other exported elements.
Pour résoudre ce problème, déplacez les types dans un espace de noms portant le même nom que la fonction :
declare namespace doSomething {
export interface Options {
// ...
}
}
declare function doSomething ( options : doSomething . Options ) : void ;
export = doSomething ;
Si vous avez besoin d'aide pour résoudre un problème, veuillez le demander sur le canal DefinitelyTyped sur le serveur Discord de la communauté TypeScript.
Si vous ajoutez des typages pour un package npm, créez un répertoire avec le même nom. Si le package pour lequel vous ajoutez des saisies n'est pas sur npm, définissez "nonNpm": true
dans le package.json
et assurez-vous que le nom que vous choisissez n'est pas en conflit avec le nom d'un package sur npm. (Vous pouvez utiliser npm info <my-package>
pour vérifier l'existence du package <my-package>
.)
Dans de rares occasions, nonNpm
peut être défini sur "conflict"
, ce qui indique qu'il existe un package sur npm portant le même nom, mais que les types entrent intentionnellement en conflit avec ce package. Cela peut être vrai pour les packages qui définissent un environnement comme @types/node
ou pour des packages factices comme aws-lambda
. Évitez d'utiliser "conflict"
lorsque cela est possible.
<my-package>-tests.ts
Il devrait y avoir un fichier <my-package>-tests.ts
, qui est considéré comme votre fichier de test, ainsi que tous les fichiers *.ts
qu'il importe. Si vous ne voyez aucun fichier de test dans le dossier du module, créez un <my-package>-tests.ts
. Ces fichiers sont utilisés pour valider l'API exportée à partir des fichiers *.d.ts
qui sont livrés sous le nom @types/<my-package>
. Ils n'expédient pas eux-mêmes.
Les modifications apportées aux fichiers *.d.ts
doivent inclure une modification correspondante du fichier *.ts
qui montre l'API utilisée, afin que personne ne casse accidentellement le code dont vous dépendez. Par exemple, cette modification apportée à une fonction dans un fichier .d.ts
ajoutant un nouveau paramètre à une fonction :
index.d.ts
:
- export function twoslash(body: string): string
+ export function twoslash(body: string, config?: { version: string }): string
<my-package>-tests.ts
:
import {twoslash} from "./"
// $ExpectType string
const result = twoslash("//")
+ // Handle options param
+ const resultWithOptions = twoslash("//", { version: "3.7" })
+ // When the param is incorrect
+ // @ts-expect-error
+ const resultWithOptions = twoslash("//", { })
Si vous vous demandez par où commencer avec le code de test, les exemples contenus dans le README du package d'origine sont un excellent point de départ.
Vous pouvez valider vos modifications avec npm test <package to test>
depuis la racine de ce dépôt, qui prend en compte les fichiers modifiés.
Utilisez $ExpectType
pour affirmer qu'une expression est d'un type donné et @ts-expect-error
pour affirmer qu'il s'agit d'une erreur de compilation. Exemples :
// $ExpectType void
f ( 1 ) ;
// @ts-expect-error
f ( "one" ) ;
Pour plus de détails, consultez le fichier readme de dtslint.
.eslintrc.json
Si, pour une raison quelconque, une règle de charpie doit être désactivée, désactivez-la pour une ligne spécifique :
// eslint-disable-next-line no-const-enum
const enum Const {
One ,
}
const enum Enum { // eslint-disable-line no-const-enum
Two ,
}
Vous pouvez toujours désactiver les règles avec un .eslintrc.json, mais cela ne devrait pas être le cas dans les nouveaux packages. La désactivation des règles pour l’ensemble du package rend la révision plus difficile.
tsconfig.json
tsconfig.json
doit avoir noImplicitAny
, noImplicitThis
, strictNullChecks
et strictFunctionTypes
définis sur true
.
Vous pouvez modifier le tsconfig.json
pour ajouter de nouveaux fichiers de test, pour ajouter "target": "es6"
(nécessaire pour les fonctions asynchrones), pour ajouter à "lib"
ou pour ajouter l'option de compilateur "jsx"
.
esModuleInterop
/ allowSyntheticDefaultImports
TL;DR : esModuleInterop
et allowSyntheticDefaultImports
ne sont pas autorisés dans votre tsconfig.json
.
Ces options permettent d'écrire une importation par défaut pour une exportation CJS, modélisant l'interopérabilité intégrée entre les modules CJS et ES dans Node et dans certains bundlers JS :
// component.d.ts declare class Component { } // CJS export, modeling `module.exports = Component` in JS export = Component ; // index.d.ts // ESM default import, only allowed under 'esModuleInterop' or 'allowSyntheticDefaultExports' import Component from "./component" ;Étant donné que la validité au moment de la compilation de l'importation dans
index.d.ts
dépend de paramètres de compilation spécifiques, dont les utilisateurs de vos types n'héritent pas, l'utilisation de ce modèle dans DefinitelyTyped forcerait les utilisateurs à modifier leurs propres paramètres de compilation, ce qui pourrait être incorrect. pour leur exécution. Au lieu de cela, vous devez écrire une importation CJS pour une exportation CJS afin de garantir une compatibilité généralisée et indépendante de la configuration :// index.d.ts // CJS import, modeling `const Component = require("./component")` in JS import Component = require ( "./component" ) ;
package.json
Ce fichier est obligatoire et doit suivre ce modèle :
{
"private" : true ,
"name" : "@types/PACKAGE-NAME" ,
"version" : "1.2.9999" ,
"projects" : [
"https://aframe.io/"
] ,
"dependencies" : {
"@types/DEPENDENCY-1" : "*" ,
"@types/DEPENDENCY-2" : "*"
} ,
"devDependencies" : {
"@types/PACKAGE-NAME" : "workspace:."
} ,
"owners" : [
{
"name" : "Your Name Here" ,
"githubUsername" : "ghost"
}
]
}
Un package.json
spécifie toutes les dépendances, y compris les autres packages @types
.
Vous devez ajouter des dépendances non @types
à la liste des dépendances externes autorisées. Pikaday en est un bon exemple. Ces ajouts sont approuvés par un responsable, ce qui nous donne la possibilité de nous assurer que les packages @types
ne dépendent pas de packages malveillants.
Si le package d'implémentation utilise ESM et spécifie "type": "module"
, vous devez alors modifier package.json pour qu'il corresponde :
{
"type" : " module "
}
Cela s'applique également si le package d'implémentation contient exports
dans son package.json.
Definitely Typed autorise peerDependencies
dans package.json
. Les dépendances entre pairs peuvent aider à éviter les situations dans lesquelles un gestionnaire de packages installe de manière inattendue des versions trop récentes ou plusieurs versions du même package. Cependant, les dépendances entre pairs ont des inconvénients ; les gestionnaires de paquets diffèrent dans leur gestion des dépendances entre pairs (par exemple, yarn
ne les installe pas automatiquement, npm
nécessite --legacy-peer-deps
pour les incompatibilités). En tant que tel, les PR introduisant de nouvelles dépendances entre pairs nécessitent l’approbation du responsable et doivent être limités à des circonstances spécifiques.
En général, les packages de types ne doivent avoir une dépendance homologue que si le package en amont a une dépendance homologue sur le même package (ou ses types). Par exemple, un package DT pour un composant React peut spécifier une dépendance homologue sur @types/react@*
, car le consommateur aura dû installer @types/react
pour utiliser JSX en premier lieu. Si le consommateur installe @types/react@16
dans son projet, mais qu'une version plus récente de @types/react
est disponible sur npm, la dépendance homologue peut aider le gestionnaire de packages à choisir @types/react@16
au lieu de cette version plus récente. De même, chai-as-promised
a une dépendance homologue sur chai
, donc @types/chai-as-promised
devrait avoir une dépendance homologue sur @types/chai
.
Il existe des cas où le package en amont n'a pas de dépendance homologue sur le package types, mais une dépendance homologue est toujours appropriée. Il s'agit généralement de cas où le package en amont étend un autre package et suppose qu'il existe, il aurait donc dû déclarer une dépendance homologue lorsqu'il étend un autre package, mais ne l'a pas fait. Par exemple, chai-match-pattern
étend chai
, mais ne déclare pas de dépendance homologue sur chai
, mais en a besoin pour fonctionner. @types/chai-match-pattern
devrait avoir une dépendance homologue sur @types/chai
.
Si un package expose simplement les types d'un autre package dans le cadre de son API en raison d'une dépendance régulière dans le package en amont, il ne doit pas utiliser de dépendance homologue. Par exemple, express
a qs
dans ses "dependencies"
. Lorsque les utilisateurs installent express
, ils n’ont pas besoin d’installer manuellement qs
. De même, @types/express
a @types/qs
dans ses "dependencies"
. Il serait incorrect de déclarer @types/qs
comme dépendance homologue de @types/express
, car cela nécessiterait que certains consommateurs en aval installent manuellement @types/qs
.
.npmignore
Ce fichier définit quels fichiers doivent être inclus dans chaque package @types
. Il doit prendre une forme spécifique. Pour les packages avec une seule version dans le dépôt :
*
! ** / * .d.ts
! ** / * .d.cts
! ** / * .d.mts
! ** / * .d. * .ts
C'est-à-dire "ignorer tous les fichiers, mais n'ignorer aucun fichier de déclaration". Pour les packages qui ont plus d'une version dans le dépôt, la "dernière" version (au niveau supérieur) doit contenir quelque chose comme :
*
! ** / * .d.ts
! ** / * .d.cts
! ** / * .d.mts
! ** / * .d. * .ts
/ v15 /
/ v16 /
/ v17 /
Ce qui est le même que le précédent .npmignore
mais en ignorant chacun des répertoires enfants versionnés.
CI échouera si ce fichier contient un contenu incorrect et fournit la valeur souhaitée. Quel que soit le contenu de ce fichier, l'éditeur ne publiera que des fichiers de déclaration.
pnpm dprint fmt -- 'path/to/package/**/*.ts'
..vscode/settings.template.json
(ou équivalent pour d'autres éditeurs) pour formater lors de l'enregistrement avec l'extension VS Code dprintfunction sum(nums: number[]): number
: Utilisez ReadonlyArray
si une fonction n'écrit pas dans ses paramètres.interface Foo { new(): Foo; }
: Ceci définit un type d'objets qui peuvent être nouveaux. Vous voulez probablement declare class Foo { constructor(); }
.const Class: { new(): IClass; }
: Préférez utiliser une déclaration de classe class Class { constructor(); }
au lieu d'une nouvelle constante.getMeAT<T>(): T
: Si un paramètre de type n'apparaît dans les types d'aucun paramètre, vous n'avez pas vraiment de fonction générique, vous avez juste une assertion de type déguisée. Préférez utiliser une assertion de type réel, par exemple getMeAT() as number
. Exemple où un paramètre de type est acceptable : function id<T>(value: T): T;
. Exemple où ce n'est pas acceptable : function parseJson<T>(json: string): T;
. Exception : new Map<string, number>()
est OK.Function
et Object
n’est presque jamais une bonne idée. Dans 99% des cas, il est possible de spécifier un type plus spécifique. Les exemples sont (x: number) => number
pour les fonctions et { x: number, y: number }
pour les objets. S'il n'y a aucune certitude quant au type, any
est le bon choix, pas Object
. Si le seul fait connu sur le type est qu'il s'agit d'un objet, utilisez le type object
, pas Object
ou { [key: string]: any }
.var foo: string | any
: Lorsque any
est utilisé dans un type union, le type résultant est toujours any
. Ainsi, même si la partie string
de cette annotation de type peut sembler utile, elle n'offre en fait aucune vérification de type supplémentaire par rapport à la simple utilisation any
. Selon l'intention, les alternatives acceptables pourraient être any
string
ou string | object
.TL;DR : ne modifiez pas
.github/CODEOWNERS
, modifiez toujours la liste des propriétaires danspackage.json
.
DT a le concept de « Propriétaires de définition », qui sont des personnes qui souhaitent maintenir la qualité des types d'un module particulier.
Pour vous ajouter en tant que propriétaire de définition, modifiez le tableau owners
dans package.json
:
"owners" : [
{
"name" : " Some Person " ,
"githubUsername" : " somebody "
},
{
"name" : " Some Corp " ,
"url" : " https://example.org "
}
]
Notez que cette liste n’est pas utilisée pour créditer les contributions ; il n'est utilisé que pour gérer les revues de relations publiques.
Une fois par semaine, les propriétaires de définitions sont synchronisés avec le fichier .github/CODEOWNERS qui est notre source de vérité.
Definitely Typed est l'un des référentiels les plus actifs sur GitHub. Vous vous demandez peut-être comment est né le projet. @johnnyreilly a écrit une histoire de Definitely Typed. Il raconte l'histoire des débuts de Definitely Typed, depuis un référentiel créé par @borisyankov, jusqu'au point où il est devenu un élément central de l'écosystème TypeScript. Vous pouvez lire l’histoire de Definitely Typed ici.
@types
sur npm ? La branche master
est automatiquement publiée dans le scope @types
sur npm grâce aux outils DefinitelyTyped.
Cela dépend, mais la plupart des demandes de tirage seront fusionnées dans un délai d'une semaine. Certains PR peuvent être fusionnés par les propriétaires d'un module et ils peuvent être fusionnés beaucoup plus rapidement. À peu près:
Les PR qui modifient uniquement les types d'un module et qui comportent des modifications de tests correspondantes seront fusionnés beaucoup plus rapidement.
Les PR qui ont été approuvés par un propriétaire répertorié dans le package.json
de la définition sont généralement fusionnés plus rapidement ; Les PR pour les nouvelles définitions prendront plus de temps car elles nécessiteront davantage d'examen de la part des responsables. Chaque PR est examiné par un membre de l'équipe TypeScript ou Definitely Typed avant d'être fusionné, alors soyez patient car des facteurs humains peuvent entraîner des retards. Consultez le tableau d'état du nouveau pull request pour voir les progrès à mesure que les responsables travaillent sur les PR ouverts.
Pour les modifications apportées à des modules très populaires, par exemple Node/Express/Jest qui comptent plusieurs millions de téléchargements chacun par semaine sur npm, les exigences de contribution sont un peu plus élevées. Les modifications apportées à ces projets peuvent avoir des effets massifs sur l’écosystème et nous traitons donc ces modifications avec beaucoup de soin. Ces modules nécessitent à la fois l'approbation d'un responsable de DT et le soutien enthousiaste des propriétaires de modules. La barre pour réussir cela peut être assez haute et souvent les PR peuvent devenir obsolètes parce qu'il n'y a pas de champion. Si vous constatez que personne ne s'engage, essayez de réduire l'objectif de vos relations publiques.
@types
npm sera-t-il mis à jour ?Les packages npm devraient être mis à jour dans une heure. Si cela fait plus d'une heure, mentionnez le numéro PR sur le canal Definitely Typed sur le serveur TypeScript Community Discord et le responsable actuel demandera au bon membre de l'équipe d'enquêter.
<reference types="" />
ou une importation ? Si le module auquel vous faites référence est un module (utilise export
), utilisez une importation. Si le module auquel vous faites référence est un module ambiant (utilise declare module
) ou déclare simplement des valeurs globales, utilisez <reference types="" />
.
tsconfig.json
qui manque "noImplicitAny": true
, "noImplicitThis": true
ou "strictNullChecks": true
.Alors ils ont tort et nous ne l’avons pas encore remarqué. Vous pouvez aider en soumettant une pull request pour les corriger.
Oui, en utilisant dprint. Nous vous recommandons d'utiliser une extension dprint pour votre éditeur.
Alternativement, vous pouvez activer un hook git qui formatera automatiquement votre code. Exécutez pnpm run setup-hooks
. Ensuite, lorsque vous validez, la commande dprint fmt
sera exécutée sur les fichiers modifiés. Si vous profitez du clonage partiel, assurez-vous d'appeler git sparse-checkout add .husky
pour vérifier les hooks git avant d'exécuter le script setup-hooks
.
Les demandes d'extraction ne nécessitent pas un formatage correct pour être fusionnées. Tout code non formaté sera automatiquement reformaté après avoir été fusionné.
Si vous êtes un utilisateur de VS Code, nous vous suggérons de copier le fichier
.vscode/settings.template.json
vers.vscode/settings.json
. Ce modèle définit l'extension dprint VS Code comme formateur par défaut dans le référentiel.
Voici les définitions actuellement demandées.
Si les types font partie d'un standard Web, ils doivent être ajoutés à TypeScript-DOM-lib-generator afin qu'ils puissent faire partie du lib.dom.d.ts
par défaut.
S'il n'y a aucun code JavaScript source, par exemple si vous écrivez des types d'assistance ou des types pour une spécification, vous devez publier les types vous-même, et non sur Definitely Typed. Parce qu'ils sont destinés à fournir des types pour le code JavaScript existant, les packages @types
ne sont pas destinés à être importés directement. Autrement dit, vous ne devez pas créer un package Definitely Typed destiné à être utilisé comme import type { ... } from "@types/foo"
. Vous ne devriez pas non plus vous attendre à écrire import type { ... } from "foo"
lorsqu'aucun foo
n'est installé.
Ceci est différent de la fourniture de types pour une bibliothèque JavaScript de navigateur uniquement ou de types pour un environnement entier comme node, bun, et al. Là, les types sont soit résolus implicitement, soit en utilisant /// <references types="foo" />
.
Certains packages, comme chai-http, exportent une fonction.
Importation de ce module avec un import de style ES6 sous la forme import * as foo from "foo";
conduit à l'erreur:
erreur TS2497 : le module 'foo' se résout en une entité non-module et ne peut pas être importé à l'aide de cette construction.
Cette erreur peut être supprimée en fusionnant la déclaration de fonction avec un espace de noms vide du même nom, mais cette pratique est déconseillée. Il s'agit d'une réponse Stack Overflow couramment citée à ce sujet.
Il est plus approprié d'importer le module en utilisant import foo = require("foo");
syntaxe. Néanmoins, si vous souhaitez utiliser une importation par défaut comme import foo from "foo";
vous avez deux options :
--allowSyntheticDefaultImports
si l'exécution de votre module prend en charge un schéma d'interopérabilité pour les modules non ECMAScript, c'est-à-dire si les importations par défaut fonctionnent dans votre environnement (par exemple Webpack, SystemJS, esm).--esModuleInterop
si vous souhaitez que TypeScript prenne en charge l'interopérabilité non-ECMAScript (depuis TypeScript 2.7). export =
, mais je préfère utiliser les importations par défaut. Puis-je changer export =
pour export default
? Comme dans la question précédente, reportez-vous à l'utilisation des options du compilateur --allowSyntheticDefaultImports
ou --esModuleInterop
.
Ne modifiez pas la définition du type si elle est exacte. Pour un package npm, export =
est précis si node -p 'require("foo")'
fonctionne pour importer un module et export default
est précis si node -p 'require("foo").default'
fonctionne pour importer un module .
Ensuite, vous aurez défini la version minimale prise en charge en spécifiant "minimumTypeScriptVersion": "XY"
dans package.json
.
Cependant, si votre projet doit conserver des types compatibles avec, disons, 3.7 et supérieur en même temps que des types compatibles avec 3.6 ou inférieur, vous devrez utiliser la fonctionnalité typesVersions
. Vous pouvez trouver une explication détaillée de cette fonctionnalité dans la documentation officielle de TypeScript.
Voici un court exemple pour vous aider à démarrer :
Vous devrez ajouter typesVersions
à package.json
:
{
"private" : true ,
"types" : " index " ,
"typesVersions" : {
"<=3.6" : { "*" : [ " ts3.6/* " ] }
}
}
Créez le sous-répertoire mentionné dans le champ typesVersions
dans votre répertoire types ( ts3.6/
dans cet exemple). ts3.6/
prendra en charge les versions TypeScript 3.6 et inférieures, alors copiez-y les types et les tests existants.
De retour à la racine du package, ajoutez les fonctionnalités TypeScript 3.7 que vous souhaitez utiliser. Lorsque les utilisateurs installent le package, TypeScript 3.6 et versions antérieures démarreront à partir de ts3.6/index.d.ts
, tandis que TypeScript 3.7 et versions ultérieures démarreront à partir de index.d.ts
.
Vous pouvez regarder bluebird pour un exemple.
Cela peut appartenir à TypeScript-DOM-lib-generator. Voir les lignes directrices ici. Si la norme est encore une ébauche, elle a sa place ici. Utilisez un nom commençant par dom-
et incluez un lien vers la norme en tant que lien « Projet » dans package.json
. Lorsqu'il passera du mode brouillon, nous pourrons le supprimer de Definitely Typed et rendre obsolète le package @types
associé.
REMARQUE : la discussion dans cette section suppose une connaissance du versioning sémantique.
Chaque package Definitely Typed est versionné lors de sa publication sur npm. Les DefinitelyTyped-tools (l'outil qui publie les packages @types
sur npm) définiront la version du package de déclaration en utilisant le numéro de version major.minor.9999
répertorié dans package.json
. Par exemple, voici les premières lignes des déclarations de type de Node pour la version 20.8.x
au moment de la rédaction :
{
"private" : true ,
"name" : " @types/node " ,
"version" : " 20.8.9999 "
}
Étant donné que la version est répertoriée comme 20.8.9999
, la version npm du package @types/node
sera également 20.8.x
. Notez que la version dans package.json
ne doit contenir que la version major.minor
(par exemple 10.12
) suivie de .9999
. En effet, seuls les numéros de version majeure et mineure sont alignés entre les packages de bibliothèque et les packages de déclaration de type. (Le .9999
permet de garantir que les packages @types
locaux sont toujours les plus récents lors du développement local.) Le numéro de version du correctif du package de déclaration de type (par exemple .0
dans 20.8.0
) est initialisé à zéro par Definitely Typed et est incrémenté à chaque fois. un nouveau package @types/node
est publié sur npm pour la même version majeure/mineure de la bibliothèque correspondante.
Parfois, les versions du package de déclaration de type et les versions du package de bibliothèque peuvent être désynchronisées. Vous trouverez ci-dessous quelques raisons courantes, classées par ordre de gêne pour les utilisateurs d'une bibliothèque. Seul ce dernier cas pose généralement problème.
@types
respectifs, alors npm update
devrait généralement fonctionner. ❗ Si vous mettez à jour les déclarations de type d'une bibliothèque, définissez toujours la version major.minor
dans package.json
pour qu'elle corresponde à la version de la bibliothèque que vous documentez ! ❗
Le versionnage sémantique exige que les versions comportant des modifications avec rupture incrémentent le numéro de version majeure. Par exemple, une bibliothèque qui supprime une fonction exportée publiquement après sa version 3.5.8
doit passer sa version à 4.0.0
dans sa prochaine version. De plus, lorsque la version 4.0.0
de la bibliothèque sera disponible, son package de déclaration de type Definitely Typed devrait également être mis à jour vers la 4.0.0
, y compris toute modification importante apportée à l'API de la bibliothèque.
De nombreuses bibliothèques ont une large base installée de développeurs (y compris les responsables d'autres packages utilisant cette bibliothèque comme dépendance) qui ne passeront pas immédiatement à une nouvelle version comportant des modifications importantes, car cela peut prendre des mois avant qu'un responsable n'ait le temps de réécrire. code à adapter à la nouvelle version. En attendant, les utilisateurs d'anciennes versions de bibliothèque souhaiteront peut-être mettre à jour les déclarations de type pour les anciennes versions.
Si vous avez l'intention de continuer à mettre à jour l'ancienne version des déclarations de type d'une bibliothèque, vous pouvez créer un nouveau sous-dossier (par exemple /v2/
) nommé pour la version actuelle (bientôt "ancienne") et y copier les fichiers existants de la version actuelle. .
Lors de la création d'un nouveau dossier de version, assurez-vous que le champ de version de package.json
a été mis à jour ; pnpm
sera automatiquement résolu en ce package versionné chaque fois que cela est nécessaire. Si d'autres packages du dépôt doivent dépendre de cette nouvelle version, assurez-vous que leurs package.json
sont également mis à jour.
Par exemple, si nous créons types/history/v2
, son package.json
ressemblerait à :
{
"private" : true ,
"name" : " @types/history " ,
"version" : " 2.4.9999 "
}
Un autre package peut sélectionner cette version en spécifiant :
{
"private" : true ,
"name" : " @types/browser-sync " ,
"version" : " 2.26.9999 " ,
"dependencies" : {
"@types/history" : " ^2 "
}
}
De plus, /// <reference types=".." />
ne fonctionnera pas avec le mappage de chemin, les dépendances doivent donc utiliser import
.
Les packages @types
tapent toujours les packages de la même version, donc @types/[email protected]
sont pour [email protected]
. En conséquence, toutes les modifications, cassées ou non, sont publiées sous forme de révisions de correctifs, à moins qu'elles ne soient associées à une modification majeure/mineure pour changer la version du package ciblée (par coïncidence ou non).
En ce qui concerne les changements majeurs, les responsables de DT prennent en compte la popularité du paquet, les avantages du changement radical proposé, l'effort qui sera requis pour les utilisateurs pour corriger leur code et si le changement pourrait raisonnablement être retardé jusqu'à ce qu'il puisse être synchronisé. avec une bosse majeure de la bibliothèque en amont.
Le manuel TypeScript contient d'excellentes informations générales sur l'écriture de définitions ainsi que cet exemple de fichier de définition qui montre comment créer une définition à l'aide de la syntaxe de module de style ES6, tout en spécifiant également les objets mis à disposition pour la portée globale. Cette technique est démontrée pratiquement dans la définition de big.js
, qui est une bibliothèque qui peut être chargée globalement via une balise de script sur une page Web ou importée via des importations require ou de style ES6.
Pour tester comment votre définition peut être utilisée à la fois lorsqu'elle est référencée globalement ou en tant que module importé, créez un dossier test
et placez-y deux fichiers de test. Nommez l’un YourLibraryName-global.test.ts
et l’autre YourLibraryName-module.test.ts
. Le fichier de test global doit exécuter la définition en fonction de la manière dont il serait utilisé dans un script chargé sur une page Web où la bibliothèque est disponible sur la portée globale. Dans ce scénario, vous ne devez pas spécifier d'instruction d'importation. Le fichier de test du module doit appliquer la définition en fonction de la manière dont il serait utilisé lors de l'importation (y compris la ou les instructions import
). Si vous spécifiez une propriété files
dans votre fichier tsconfig.json
, assurez-vous d'inclure les deux fichiers de test. Un exemple pratique de ceci est également disponible sur la définition big.js
Veuillez noter qu'il n'est pas nécessaire d'exercer pleinement la définition dans chaque fichier de test - il suffit de tester uniquement les éléments accessibles globalement du fichier de test global et d'exercer pleinement la définition dans le fichier de test du module ou vice versa.
Les types pour un package à portée @foo/bar
doivent aller en types/foo__bar
. Notez le double soulignement.
Ce projet est sous licence MIT.
Les droits d'auteur sur les fichiers de définition sont respectifs de chaque contributeur répertorié au début de chaque fichier de définition.