1645601308
Apprenez à utiliser les fonctions dans TypeScript. Apprenez à définir des types pour les paramètres et les types de retour, à créer des types de fonction et plus encore.
Les fonctions font partie intégrante de JavaScript. Ils aident à rendre le code réutilisable tout en le gardant flexible. TypeScript va encore plus loin dans ces avantages en vous aidant à écrire des fonctions de type sécurisées. Ce didacticiel vous montrera comment utiliser les fonctions dans TypeScript, comment spécifier des types pour les paramètres, les types de retour et plus encore.
Les fonctions sont parmi les fonctionnalités de langage les plus fréquemment utilisées. Cela s'applique non seulement à JavaScript et à TypeScript, mais également à d'autres langages de programmation. En JavaScript cependant, il y a un problème. JavaScript n'est pas un langage de programmation de type statique. À cause de cela, il y a certaines choses que vous ne pouvez pas faire.
Par exemple, lorsque vous définissez une fonction, vous ne pouvez pas spécifier les types autorisés pour ses paramètres. Cela facilite l'appel d'une fonction avec un argument d'un type incorrect. Vous pouvez créer une fonction qui prend deux nombres comme paramètres et l'appeler en passant deux chaînes comme arguments. JavaScript ne vous arrêtera pas.
Vous ne pouvez pas non plus spécifier le type de retour d'une fonction. Cela peut entraîner des problèmes lorsqu'une partie du programme appelant une fonction s'attend à obtenir une chose alors que la fonction renvoie quelque chose de différent. C'est là que TypeScript peut être utile. Il est vrai que TypeScript n'apporte vraiment rien de nouveau aux fonctions.
Les fonctions dans TypeScript sont toujours des fonctions, ces fonctions que vous connaissez de JavaScript. Ce que fait TypeScript, c'est qu'il rend les fonctions plus sûres, plus prévisibles. Il le fait en combinant des fonctions avec son système de type puissant. Cela vous aide à vous assurer que vos fonctions reçoivent et renvoient les types corrects. Voyons comment.
Lorsque vous créez une fonction, vous pouvez également spécifier les paramètres qu'elle accepte. Cela rend votre code plus flexible et plus facile à réutiliser dans différentes conditions. Avec TypeScript, vous pouvez également spécifier des types pour ces paramètres. Lorsque vous essayez d'appeler une fonction avec un argument d'un type incorrect, TypeScript vous avertit.
La syntaxe de définition des types pour les paramètres de fonction est simple. Il est composé de deux-points ( :
) et du type. Tout d'abord, vous définissez un paramètre. Ensuite, vous ajoutez deux-points juste après. Après cela, vous spécifiez quel type est autorisé pour ce paramètre spécifique.
// Create a function that accepts two parameters: str1 and str2.
// Both parameters must be of type string.
function joinStrings(str1: string, str2: string) {
return str1 + str2
}
// This will work:
joinStrings('Wo', 'rld')
// Output:
// 'World'
// This will not work:
joinStrings('Hel', 135)
// TS error: Argument of type 'number' is not assignable to parameter of type 'string'.
TypeScript vous permet également de spécifier plusieurs types. Vous pouvez y parvenir en utilisant des types d'union . Cela signifie essentiellement que vous pouvez prendre deux types ou plus et indiquer à TypeScript que l'un de ces types peut être utilisé. Lorsque vous souhaitez utiliser des types d'union, vous spécifiez tous les types possibles et utilisez |
pour les séparer.
// Create a function that accepts one parameter.
// This parameter can be either number, string or boolean.
function numStrBool(val: number | string | boolean) {
return typeof val
}
// This will work in TypeScript:
numStrBool(15)
// Output:
// 'number'
// This will also work in TypeScript:
numStrBool('Tea')
// Output:
// 'string'
// This will also work in TypeScript:
numStrBool(true)
// Output:
// 'boolean'
// This will not work in TypeScript:
numStrBool({ key: 15 })
// TS error: Argument of type '{ key: number; }' is not assignable to parameter of type 'string | number | boolean'.
Tout comme en JavaScript, vous pouvez également marquer certains paramètres comme facultatifs dans TypeScript. La syntaxe est la même. Pour marquer un paramètre comme facultatif, ajoutez un point d'interrogation ( ?
) juste après. Lorsque vous travaillez avec des fonctions dans TypeScript, le point d'interrogation se place après le nom du paramètre et avant les deux-points et le type.
// Create a function that accepts two parameters,
// the first one required and the second optional:
function combineWords(word1: string, word2?: string) {
return `${word1}${word2 ? word2 : ''}`
}
// This will work in TypeScript:
combineWords('Hello', 'world')
// Output:
// 'Helloworld'
// This will also work in TypeScript:
combineWords('Say', 'Bye')
// Output:
// 'SayBye'
// This will also work in TypeScript:
combineWords('Hi')
// Output:
// 'Hi'
// This will not work in TypeScript:
combineWords()
// TS error: Expected 1-2 arguments, but got 0.
TypeScript vous permet également de définir des valeurs par défaut pour les paramètres de fonction. Ce n'est pas tout. Lorsque vous définissez des valeurs par défaut pour les fonctions dans TypeScript, vous n'avez pas à spécifier explicitement les types de ces paramètres. TypeScript pourra utiliser les valeurs par défaut pour déduire automatiquement les types des paramètres. Moins de travail pour vous.
La syntaxe des valeurs par défaut est la même qu'en JavaScript . Vous spécifiez un paramètre et juste après, ajoutez un signe égal avec la valeur par défaut. Si vous souhaitez également spécifier explicitement un type pour le paramètre, vous devez d'abord spécifier le type. Cela signifie utiliser l'ordre suivant : nom du paramètre, deux-points et type, signe égal et valeur par défaut.
// Example 1: default parameters and implicit type:
// Create a function that accepts two parameters.
// Both parameters are of type numbers,
// the second has default value 0.
function addTwoNumbers(num1: number, num2 = 0) {
return num1 + num2
}
// TS will add type for num2 implicitly:
// addTwoNumbers(num1: number, num2: number = 0)
// This will work in TypeScript:
addTwoNumbers(98, 656)
// Output:
// 754
// This will also work in TypeScript:
addTwoNumbers(63)
// Output:
// 63
// This will not work in TypeScript:
addTwoNumbers('13')
// TS error: Argument of type 'string' is not assignable to parameter of type 'number'.
// Example 2: default parameters and explicit type:
function addTwoNumbers(num1: number, num2: number = 0) {
return num1 + num2
}
Certaines fonctions peuvent accepter un nombre arbitraire d'arguments. C'est là que la syntaxe des paramètres de repos sera très utile. Dans TypeScript, vous pouvez spécifier le type des paramètres de repos aussi facilement que n'importe quel autre paramètre. La syntaxe est la même. Vous ajoutez le paramètre rest et le suivez avec deux-points et le type.
Lorsque vous travaillez avec des paramètres de repos, souvenez-vous d'une chose. Les paramètres passés en tant que paramètres de repos seront collectés dans un tableau. Cela signifie que vous devez également utiliser le type de tableau, soit type[]
ou Array<type>
.
// Create a function that accepts two parameters.
// The first parameter is a string.
// The second is a rest parameter and is an array of strings.
function buildATeam(leader: string, ...teammates: string[]) {
return `Team is composed of ${leader} as a the team leader and ${teammates.length > 0 ? teammates.join(', ') : 'nobody'} as the core team.`
}
// This will work in TypeScript:
buildATeam('Joe', 'Vicky', 'Thomas')
// Output:
// 'Team is composed of Joe as a the team leader and Vicky, Thomas as the core team.'
// This will also work in TypeScript:
buildATeam('Sandra', 'Alex', 'Jack', 'Victor')
// Output:
// 'Team is composed of Sandra as a the team leader and Alex, Jack, Victor as the core team.'
// This will also work in TypeScript:
buildATeam('Stuart')
// Output:
// 'Team is composed of Stuart as a the team leader and nobody as the core team.'
// This will not work in TypeScript:
buildATeam(13, 15)
// TS error: Argument of type 'number' is not assignable to parameter of type 'string'.
TypeScript vous permet également de spécifier le type de retour d'une fonction. Cela dit, vous ne vous retrouverez pas à le faire très souvent. Dans la plupart des cas, TypeScript pourra déduire le type de retour de la fonction en fonction des instructions de retour à l'intérieur de la fonction elle-même. Vous n'avez pas besoin de spécifier explicitement ces types.
Que se passe-t-il si TypeScript n'est pas en mesure de déduire le type de retour ou si vous souhaitez le spécifier vous-même ? Afin de spécifier le type de retour de la fonction, vous devez ajouter deux-points et le type juste après la liste des paramètres, avant le corps de la fonction.
// Create a function that accepts two parameters.
// Both parameters are numbers.
// Set the return type to be a number (the '): number {' part).
function numToPow(num: number, exp: number): number {
return num ** exp
}
// This will work in TypeScript:
numToPow(15, 8)
// Output:
// 2562890625
// This will not work in TypeScript:
numToPow(12, '9')
// TS error: Argument of type 'string' is not assignable to parameter of type 'number'.
Lorsque vous travaillez avec des fonctions dans TypeScript, vous définissez généralement tous ses types lorsque vous déclarez une fonction. Ce que TypeScript permet également, c'est de définir une signature de fonction avant de créer la fonction elle-même. Plus tard, lorsque vous créerez la fonction, TypeScript utilisera la signature pour déduire automatiquement tous les types pour vous.
Cette signature est appelée un type de fonction. Cela peut être utile lorsque vous attendez une signature de fonction spécifique. Ce type de fonction est composé de deux parties : les paramètres et le type de retour. Lorsque vous déclarez un type de fonction, vous devez spécifier ces deux parties.
// Create function type for function subtract.
// This function accepts two parameters, both are numbers.
// Its return type is also a number.
let subtract: (a: number, b: number) => number
// Assign the actual function to the variable:
subtract = function (a, b) {
return a - b
}
// This will not work in TypeScript:
subtract = function (a: string, b: string) {
return a + b
}
// TS error: Type '(a: string, b: string) => string' is not assignable to type '(a: number, b: number) => number'.
N'oubliez pas que lorsque vous déclarez le type de fonction, vous n'avez pas à spécifier à nouveau les types lorsque vous affectez la fonction réelle. TypeScript déduira implicitement tous les types en fonction du type de fonction que vous avez créé précédemment.
// Create function type for function subtract:
let subtract: (a: number, b: number) => number
// These types are redundant:
subtract = function (a: number, b: number) {
return a - b
}
Il existe un autre moyen d'y parvenir. Vous pouvez également créer un type de fonction lors de l'affectation de la fonction. Cela vous permet de combiner les deux étapes en une seule.
// Create function with function:
let subtract: (a: number, b: number) => number = function (a: number, b: number) {
return a - b
}
Ces façons de créer un type de fonction dont nous venons de parler ont un inconvénient. Ils ne sont pas vraiment réutilisables. Vous créez un type de fonction, vous lui affectez une fonction et vous avez terminé. Vous ne pouvez pas réutiliser ce type pour une autre fonction, sauf si vous copiez le code. Heureusement, il existe un autre moyen, deux en fait.
Vous pouvez également créer des types de fonction avec des types et des interfaces . L'avantage des deux est la réutilisation déjà mentionnée. Le type et l'interface ne cesseront pas d'exister après leur utilisation. Lorsque vous créez un type de fonction avec un type ou une interface, vous pouvez l'utiliser quand vous le souhaitez et autant de fois que vous le souhaitez.
La syntaxe de type pour déclarer un type de fonction est très similaire à la syntaxe que vous avez vue ci-dessus. Il n'y a que deux différences. Tout d'abord, vous remplacerez la variable mot-clé par type
mot-clé. Deuxièmement, vous remplacerez les deux-points après le nom de la variable par le signe égal. Vous créez essentiellement un nouveau type et lui attribuez une signature de fonction.
Lorsque vous souhaitez utiliser votre nouveau type, vous l'utilisez avec les deux-points lorsque vous créez une nouvelle expression de fonction .
// Function type with variable:
let subtract: (a: number, b: number) => number
// Function type with type:
type TakeNumsReturnNums = (a: number, b: number) => number
// Use the "TakeNumsReturnNums" type with function expression:
const subtract: TakeNumsReturnNums = (a, b) => a - b
// This will work in TypeScript:
subtract(97, 13)
// Output:
// 84
// This will not work in TypeScript:
subtract(55, '15')
// TS error: Argument of type 'string' is not assignable to parameter of type 'number'.
// Use the type again:
const sumNumbers: TakeNumsReturnNums = (x, y) => x + y
// And again:
const divideNumbers: TakeNumsReturnNums = (c, d) => c / d
Faire la même chose avec une interface nécessite une syntaxe différente. Vous créez une nouvelle interface. À l'intérieur, vous spécifierez les types de liste de paramètres comme clé et le type de retour comme valeur. Ensuite, vous l'utilisez de la même manière que le type.
// Create interface for subtract function:
interface TakeNumsReturnNums {
// Syntax:
// (types for parameter list): return type;
(a: number, b: number): number;
}
// Use the "TakeNumsReturnNums" interface with function expression:
const subtract: TakeNumsReturnNums = (a, b) => a - b
// This will work in TypeScript:
subtract(55, 21)
// Output:
// 34
// This will not work in TypeScript:
subtract(true, 66)
// TS error: Argument of type 'boolean' is not assignable to parameter of type 'number'.
// Use the type again:
const sumNumbers: TakeNumsReturnNums = (x, y) => x + y
// And again:
const divideNumbers: TakeNumsReturnNums = (c, d) => c / d
TypeScript facilite l'écriture de fonctions dont le type est sûr et plus prévisible. J'espère que ce tutoriel vous a aidé à comprendre comment utiliser les fonctions dans TypeScript. Comment définir des types pour les paramètres et les types de retour et comment créer des types de fonction.
1654588030
TypeScript Deep Dive
I've been looking at the issues that turn up commonly when people start using TypeScript. This is based on the lessons from Stack Overflow / DefinitelyTyped and general engagement with the TypeScript community. You can follow for updates and don't forget to ★ on GitHub 🌹
If you are here to read the book online get started.
Book is completely free so you can copy paste whatever you want without requiring permission. If you have a translation you want me to link here. Send a PR.
You can also download one of the Epub, Mobi, or PDF formats from the actions tab by clicking on the latest build run. You will find the files in the artifacts section.
All the amazing contributors 🌹
Share URL: https://basarat.gitbook.io/typescript/
Author: Basarat
Source Code: https://github.com/basarat/typescript-book/
License: View license
1645601308
Apprenez à utiliser les fonctions dans TypeScript. Apprenez à définir des types pour les paramètres et les types de retour, à créer des types de fonction et plus encore.
Les fonctions font partie intégrante de JavaScript. Ils aident à rendre le code réutilisable tout en le gardant flexible. TypeScript va encore plus loin dans ces avantages en vous aidant à écrire des fonctions de type sécurisées. Ce didacticiel vous montrera comment utiliser les fonctions dans TypeScript, comment spécifier des types pour les paramètres, les types de retour et plus encore.
Les fonctions sont parmi les fonctionnalités de langage les plus fréquemment utilisées. Cela s'applique non seulement à JavaScript et à TypeScript, mais également à d'autres langages de programmation. En JavaScript cependant, il y a un problème. JavaScript n'est pas un langage de programmation de type statique. À cause de cela, il y a certaines choses que vous ne pouvez pas faire.
Par exemple, lorsque vous définissez une fonction, vous ne pouvez pas spécifier les types autorisés pour ses paramètres. Cela facilite l'appel d'une fonction avec un argument d'un type incorrect. Vous pouvez créer une fonction qui prend deux nombres comme paramètres et l'appeler en passant deux chaînes comme arguments. JavaScript ne vous arrêtera pas.
Vous ne pouvez pas non plus spécifier le type de retour d'une fonction. Cela peut entraîner des problèmes lorsqu'une partie du programme appelant une fonction s'attend à obtenir une chose alors que la fonction renvoie quelque chose de différent. C'est là que TypeScript peut être utile. Il est vrai que TypeScript n'apporte vraiment rien de nouveau aux fonctions.
Les fonctions dans TypeScript sont toujours des fonctions, ces fonctions que vous connaissez de JavaScript. Ce que fait TypeScript, c'est qu'il rend les fonctions plus sûres, plus prévisibles. Il le fait en combinant des fonctions avec son système de type puissant. Cela vous aide à vous assurer que vos fonctions reçoivent et renvoient les types corrects. Voyons comment.
Lorsque vous créez une fonction, vous pouvez également spécifier les paramètres qu'elle accepte. Cela rend votre code plus flexible et plus facile à réutiliser dans différentes conditions. Avec TypeScript, vous pouvez également spécifier des types pour ces paramètres. Lorsque vous essayez d'appeler une fonction avec un argument d'un type incorrect, TypeScript vous avertit.
La syntaxe de définition des types pour les paramètres de fonction est simple. Il est composé de deux-points ( :
) et du type. Tout d'abord, vous définissez un paramètre. Ensuite, vous ajoutez deux-points juste après. Après cela, vous spécifiez quel type est autorisé pour ce paramètre spécifique.
// Create a function that accepts two parameters: str1 and str2.
// Both parameters must be of type string.
function joinStrings(str1: string, str2: string) {
return str1 + str2
}
// This will work:
joinStrings('Wo', 'rld')
// Output:
// 'World'
// This will not work:
joinStrings('Hel', 135)
// TS error: Argument of type 'number' is not assignable to parameter of type 'string'.
TypeScript vous permet également de spécifier plusieurs types. Vous pouvez y parvenir en utilisant des types d'union . Cela signifie essentiellement que vous pouvez prendre deux types ou plus et indiquer à TypeScript que l'un de ces types peut être utilisé. Lorsque vous souhaitez utiliser des types d'union, vous spécifiez tous les types possibles et utilisez |
pour les séparer.
// Create a function that accepts one parameter.
// This parameter can be either number, string or boolean.
function numStrBool(val: number | string | boolean) {
return typeof val
}
// This will work in TypeScript:
numStrBool(15)
// Output:
// 'number'
// This will also work in TypeScript:
numStrBool('Tea')
// Output:
// 'string'
// This will also work in TypeScript:
numStrBool(true)
// Output:
// 'boolean'
// This will not work in TypeScript:
numStrBool({ key: 15 })
// TS error: Argument of type '{ key: number; }' is not assignable to parameter of type 'string | number | boolean'.
Tout comme en JavaScript, vous pouvez également marquer certains paramètres comme facultatifs dans TypeScript. La syntaxe est la même. Pour marquer un paramètre comme facultatif, ajoutez un point d'interrogation ( ?
) juste après. Lorsque vous travaillez avec des fonctions dans TypeScript, le point d'interrogation se place après le nom du paramètre et avant les deux-points et le type.
// Create a function that accepts two parameters,
// the first one required and the second optional:
function combineWords(word1: string, word2?: string) {
return `${word1}${word2 ? word2 : ''}`
}
// This will work in TypeScript:
combineWords('Hello', 'world')
// Output:
// 'Helloworld'
// This will also work in TypeScript:
combineWords('Say', 'Bye')
// Output:
// 'SayBye'
// This will also work in TypeScript:
combineWords('Hi')
// Output:
// 'Hi'
// This will not work in TypeScript:
combineWords()
// TS error: Expected 1-2 arguments, but got 0.
TypeScript vous permet également de définir des valeurs par défaut pour les paramètres de fonction. Ce n'est pas tout. Lorsque vous définissez des valeurs par défaut pour les fonctions dans TypeScript, vous n'avez pas à spécifier explicitement les types de ces paramètres. TypeScript pourra utiliser les valeurs par défaut pour déduire automatiquement les types des paramètres. Moins de travail pour vous.
La syntaxe des valeurs par défaut est la même qu'en JavaScript . Vous spécifiez un paramètre et juste après, ajoutez un signe égal avec la valeur par défaut. Si vous souhaitez également spécifier explicitement un type pour le paramètre, vous devez d'abord spécifier le type. Cela signifie utiliser l'ordre suivant : nom du paramètre, deux-points et type, signe égal et valeur par défaut.
// Example 1: default parameters and implicit type:
// Create a function that accepts two parameters.
// Both parameters are of type numbers,
// the second has default value 0.
function addTwoNumbers(num1: number, num2 = 0) {
return num1 + num2
}
// TS will add type for num2 implicitly:
// addTwoNumbers(num1: number, num2: number = 0)
// This will work in TypeScript:
addTwoNumbers(98, 656)
// Output:
// 754
// This will also work in TypeScript:
addTwoNumbers(63)
// Output:
// 63
// This will not work in TypeScript:
addTwoNumbers('13')
// TS error: Argument of type 'string' is not assignable to parameter of type 'number'.
// Example 2: default parameters and explicit type:
function addTwoNumbers(num1: number, num2: number = 0) {
return num1 + num2
}
Certaines fonctions peuvent accepter un nombre arbitraire d'arguments. C'est là que la syntaxe des paramètres de repos sera très utile. Dans TypeScript, vous pouvez spécifier le type des paramètres de repos aussi facilement que n'importe quel autre paramètre. La syntaxe est la même. Vous ajoutez le paramètre rest et le suivez avec deux-points et le type.
Lorsque vous travaillez avec des paramètres de repos, souvenez-vous d'une chose. Les paramètres passés en tant que paramètres de repos seront collectés dans un tableau. Cela signifie que vous devez également utiliser le type de tableau, soit type[]
ou Array<type>
.
// Create a function that accepts two parameters.
// The first parameter is a string.
// The second is a rest parameter and is an array of strings.
function buildATeam(leader: string, ...teammates: string[]) {
return `Team is composed of ${leader} as a the team leader and ${teammates.length > 0 ? teammates.join(', ') : 'nobody'} as the core team.`
}
// This will work in TypeScript:
buildATeam('Joe', 'Vicky', 'Thomas')
// Output:
// 'Team is composed of Joe as a the team leader and Vicky, Thomas as the core team.'
// This will also work in TypeScript:
buildATeam('Sandra', 'Alex', 'Jack', 'Victor')
// Output:
// 'Team is composed of Sandra as a the team leader and Alex, Jack, Victor as the core team.'
// This will also work in TypeScript:
buildATeam('Stuart')
// Output:
// 'Team is composed of Stuart as a the team leader and nobody as the core team.'
// This will not work in TypeScript:
buildATeam(13, 15)
// TS error: Argument of type 'number' is not assignable to parameter of type 'string'.
TypeScript vous permet également de spécifier le type de retour d'une fonction. Cela dit, vous ne vous retrouverez pas à le faire très souvent. Dans la plupart des cas, TypeScript pourra déduire le type de retour de la fonction en fonction des instructions de retour à l'intérieur de la fonction elle-même. Vous n'avez pas besoin de spécifier explicitement ces types.
Que se passe-t-il si TypeScript n'est pas en mesure de déduire le type de retour ou si vous souhaitez le spécifier vous-même ? Afin de spécifier le type de retour de la fonction, vous devez ajouter deux-points et le type juste après la liste des paramètres, avant le corps de la fonction.
// Create a function that accepts two parameters.
// Both parameters are numbers.
// Set the return type to be a number (the '): number {' part).
function numToPow(num: number, exp: number): number {
return num ** exp
}
// This will work in TypeScript:
numToPow(15, 8)
// Output:
// 2562890625
// This will not work in TypeScript:
numToPow(12, '9')
// TS error: Argument of type 'string' is not assignable to parameter of type 'number'.
Lorsque vous travaillez avec des fonctions dans TypeScript, vous définissez généralement tous ses types lorsque vous déclarez une fonction. Ce que TypeScript permet également, c'est de définir une signature de fonction avant de créer la fonction elle-même. Plus tard, lorsque vous créerez la fonction, TypeScript utilisera la signature pour déduire automatiquement tous les types pour vous.
Cette signature est appelée un type de fonction. Cela peut être utile lorsque vous attendez une signature de fonction spécifique. Ce type de fonction est composé de deux parties : les paramètres et le type de retour. Lorsque vous déclarez un type de fonction, vous devez spécifier ces deux parties.
// Create function type for function subtract.
// This function accepts two parameters, both are numbers.
// Its return type is also a number.
let subtract: (a: number, b: number) => number
// Assign the actual function to the variable:
subtract = function (a, b) {
return a - b
}
// This will not work in TypeScript:
subtract = function (a: string, b: string) {
return a + b
}
// TS error: Type '(a: string, b: string) => string' is not assignable to type '(a: number, b: number) => number'.
N'oubliez pas que lorsque vous déclarez le type de fonction, vous n'avez pas à spécifier à nouveau les types lorsque vous affectez la fonction réelle. TypeScript déduira implicitement tous les types en fonction du type de fonction que vous avez créé précédemment.
// Create function type for function subtract:
let subtract: (a: number, b: number) => number
// These types are redundant:
subtract = function (a: number, b: number) {
return a - b
}
Il existe un autre moyen d'y parvenir. Vous pouvez également créer un type de fonction lors de l'affectation de la fonction. Cela vous permet de combiner les deux étapes en une seule.
// Create function with function:
let subtract: (a: number, b: number) => number = function (a: number, b: number) {
return a - b
}
Ces façons de créer un type de fonction dont nous venons de parler ont un inconvénient. Ils ne sont pas vraiment réutilisables. Vous créez un type de fonction, vous lui affectez une fonction et vous avez terminé. Vous ne pouvez pas réutiliser ce type pour une autre fonction, sauf si vous copiez le code. Heureusement, il existe un autre moyen, deux en fait.
Vous pouvez également créer des types de fonction avec des types et des interfaces . L'avantage des deux est la réutilisation déjà mentionnée. Le type et l'interface ne cesseront pas d'exister après leur utilisation. Lorsque vous créez un type de fonction avec un type ou une interface, vous pouvez l'utiliser quand vous le souhaitez et autant de fois que vous le souhaitez.
La syntaxe de type pour déclarer un type de fonction est très similaire à la syntaxe que vous avez vue ci-dessus. Il n'y a que deux différences. Tout d'abord, vous remplacerez la variable mot-clé par type
mot-clé. Deuxièmement, vous remplacerez les deux-points après le nom de la variable par le signe égal. Vous créez essentiellement un nouveau type et lui attribuez une signature de fonction.
Lorsque vous souhaitez utiliser votre nouveau type, vous l'utilisez avec les deux-points lorsque vous créez une nouvelle expression de fonction .
// Function type with variable:
let subtract: (a: number, b: number) => number
// Function type with type:
type TakeNumsReturnNums = (a: number, b: number) => number
// Use the "TakeNumsReturnNums" type with function expression:
const subtract: TakeNumsReturnNums = (a, b) => a - b
// This will work in TypeScript:
subtract(97, 13)
// Output:
// 84
// This will not work in TypeScript:
subtract(55, '15')
// TS error: Argument of type 'string' is not assignable to parameter of type 'number'.
// Use the type again:
const sumNumbers: TakeNumsReturnNums = (x, y) => x + y
// And again:
const divideNumbers: TakeNumsReturnNums = (c, d) => c / d
Faire la même chose avec une interface nécessite une syntaxe différente. Vous créez une nouvelle interface. À l'intérieur, vous spécifierez les types de liste de paramètres comme clé et le type de retour comme valeur. Ensuite, vous l'utilisez de la même manière que le type.
// Create interface for subtract function:
interface TakeNumsReturnNums {
// Syntax:
// (types for parameter list): return type;
(a: number, b: number): number;
}
// Use the "TakeNumsReturnNums" interface with function expression:
const subtract: TakeNumsReturnNums = (a, b) => a - b
// This will work in TypeScript:
subtract(55, 21)
// Output:
// 34
// This will not work in TypeScript:
subtract(true, 66)
// TS error: Argument of type 'boolean' is not assignable to parameter of type 'number'.
// Use the type again:
const sumNumbers: TakeNumsReturnNums = (x, y) => x + y
// And again:
const divideNumbers: TakeNumsReturnNums = (c, d) => c / d
TypeScript facilite l'écriture de fonctions dont le type est sûr et plus prévisible. J'espère que ce tutoriel vous a aidé à comprendre comment utiliser les fonctions dans TypeScript. Comment définir des types pour les paramètres et les types de retour et comment créer des types de fonction.
1657590960
Dans cet article, vous apprendrez à utiliser Pick in TypeScript pour vous aider à nettoyer votre base de code et à rendre votre gestion des types beaucoup plus simple et plus propre !
Qu'est-ce que c'est Pick
? Pick est ce qu'on appelle un type mappé, et j'ai couvert d'autres types mappés dans mon cours TypeScript Masterclass .
Voici la syntaxe pour Pick
:
Pick<Type, Keys>
Nous passons dans un existant Type
puis déclarons le Keys
que nous souhaitons "choisir" dans le Type
. Avoir du sens ? Ils Keys
doivent exister sur le Type
pour que vous puissiez les "choisir", sinon vous verrez une erreur TypeScript.
🛹 Le comportement inverse serait d'utiliser à la place le type Omit de TypeScript .
Les types mappés nous permettent de construire dynamiquement de nouveaux types à partir de ceux existants, créant ainsi un nouveau type avec une nouvelle signification. Cela nous permet de créer de nouveaux types à la volée, sans avoir à déclarer de nouveaux types ou interfaces.
Par exemple, voici un service d'authentification commun sur lequel j'ai travaillé récemment, écrit en Angular et Firebase :
@Injectable({
providedIn: 'root',
})
export class AuthService {
constructor() {}
async create({ name, email, password }: any) {...}
async login({ email, password }: any) {...}
async resetPassword({ email }: any) {...}
}
Vous remarquerez que nous utilisons essentiellement les mêmes propriétés pour « créer », « se connecter » et « réinitialiser » un mot de passe. Nous utilisons un mélange de name
, email
, password
.
Comment pourrions-nous taper cela? 🤔
En utilisant le mot- type
clé, nous pourrions construire séparément chaque propriété que nous attendons et utiliser un type d'intersection pour combiner les types en de nouveaux :
type Name = { name: string };
type Email = { email: string };
type Password = { password: string };
type CreateUser = Name & Email & Password; // { name: string, email: string, password: string }
type LoginUser = Email & Password; // { email: string, password: string }
type ResetPassword = Email; // { email: string }
Nous pourrions alors le faire pour ajouter les types aux bons endroits :
@Injectable({
providedIn: 'root',
})
export class AuthService {
constructor() {}
async create({ name, email, password }: CreateUser) {...}
async login({ email, password }: LoginUser) {...}
async resetPassword({ email }: ResetPassword) {...}
}
C'est correct pour une utilisation aussi simple, mais vous pouvez imaginer étendre votre base de code avec des fonctionnalités plus complexes et tout à coup, les choses commencent à devenir incontrôlables dans un type
monde de douleur.
C'est là Pick
qu'entre en jeu. Je vise un code minimal. Aucun code n'est un bon code !
Comme nous avons déjà examiné la syntaxe, Pick
accepte un existant Type
, puis les propriétés ( Keys
) que vous souhaitez "choisir" à partir de celui-ci.
Commençons par créer un Credentials
type via an interface
, qui remplacera notre pile de type
déclarations et introduira un peu Pick
de magie :
export interface Credentials {
name: string;
email: string;
password: string;
}
Tout d'abord, c'est beaucoup plus facile à lire et à gérer.
Deuxièmement, je préfère utiliser interface
a plutôt que a type
sauf si je compose des types plus complexes , ce qui, à mon avis, n'est pas particulièrement complexe.
À l' aide Pick
de , nous pouvons dire à TypeScript de choisir ceux qui sont particuliers Keys
parmi nos existants Type
(qui pourraient être un interface
ou type
).
Cela nous permet de construire intelligemment un nouveau type à partir de l'utilisation de Pick
, mais d'utiliser uniquement les propriétés pertinentes (en ignorant les autres) :
export interface Credentials {
name: string;
email: string;
password: string;
}
@Injectable({
providedIn: 'root',
})
export class AuthService {
constructor() {}
async create({ name, email, password }: Credentials) {...}
async login({ email, password }: Pick<Credentials, 'email' | 'password'>) {...}
async resetPassword({ email }: Pick<Credentials, 'email'>) {...}
}
Beaucoup plus propre, et tous les types sont conservés au même endroit. Si vous êtes susceptible de les réutiliser, vous pouvez bien sûr également les décomposer en mots- type
clés que je vous montrerai dans un instant.
🚨 Conseil de pro : Attention à ne pas confondre le
'email' | 'password'
avec un Type Union . Dans un type mappé tel que Pick, cette|
syntaxe est plus « et » au lieu de « ou ».
Si nous devions à l'avenir modifier l' Credentials
interface, les nouvelles définitions circuleront dans le reste du code, plutôt que de mettre à jour manuellement chaque type d'intersection.
Pick
est un excellent utilitaire Mapped Type qui nous facilite beaucoup les choses, je vous encourage fortement à l'utiliser à votre avantage pour garder votre base de code propre !
🕵️♂️ Vous pouvez également consulter la brève documentation Pick si vous le souhaitez également.
Et promis, voici comment vous pouvez créer de nouveaux types avec les Pick
types résultants, ce qui vous permettrait de les utiliser ailleurs sans répéter le même code.
export interface Credentials {
name: string;
email: string;
password: string;
}
type LoginUser = Pick<Credentials, 'email' | 'password'>;
type ResetPassword = Pick<Credentials, 'email'>;
Dans tous les cas, c'est beaucoup plus facile à voir ! Nous bénéficions également d'avantages intellisense supplémentaires en utilisant un interface
au lieu d'un type
.
En savoir plus sur Interfaces vs Types dans un article précédent que j'ai rédigé sur le sujet - un peu plus approfondi !
Découvrez l'exemple en direct dans StackBlitz, jouez et voyez comment cela fonctionne :
https://stackblitz.com/edit/typescript-6uqypw?file=index.ts
Bonne cueillette et merci d'avoir lu !
Source : https://ultimatecourses.com/blog/using-typescript-pick-mapped-type
1656580800
TypeScript est très apprécié par la communauté des développeurs pour de nombreuses raisons, dont l'une est due aux vérifications statiques qu'il fournit au code qui y est écrit.
Repérer les problèmes au début de votre cycle de vie de développement peut vous faire gagner des jours de débogage d'erreurs aléatoires et vagues qui peuvent parfois apparaître lors de l'utilisation de langages dynamiques comme JavaScript.
TypeScript peut vous aider à rendre votre code plus prévisible et mieux documenté, à faciliter la refactorisation et à réduire les erreurs potentielles que vous pourriez rencontrer lors de l'exécution dans votre application de production. Sa popularité et sa puissance sont démontrées par son taux de satisfaction des développeurs de 93 % et son utilisation en flèche au cours des cinq dernières années.
Les énumérations sont un mécanisme de langage essentiel à TypeScript.
Les énumérations ne sont pas une fonctionnalité de frappe, ce qui est intéressant, comme la plupart de TypeScript - en fait, elles sont l'une des rares nouvelles fonctionnalités qui améliorent le langage.
Les énumérations permettent aux développeurs de définir un ensemble strict d'options pour une variable. Par exemple:
enum Door {
Open,
Closed,
Ajar // half open, half closed
}
Les énumérations par défaut sont des énumérations numériques, donc l'énumération ci-dessus est essentiellement un objet avec 0
, 1
et 2
comme clé, que nous pouvons voir dans le code JavaScript transpilé .
"use strict";
var Door;
(function (Door) {
Door[Door["Open"] = 0] = "Open";
Door[Door["Closed"] = 1] = "Closed";
Door[Door["Ajar"] = 2] = "Ajar"; // half open, half closed
})(Door || (Door = {}));
console.log(Door.FullyOpened);
Dans TypeScript, vous pouvez également utiliser des énumérations de chaînes, comme ceci :
enum Door {
Open = "open",
Closed = "closed",
Ajar = "ajar" // half open, half closed
}
Si vous utilisiez ensuite cette Door
énumération, vous pourriez vous assurer que les variables n'utilisaient que les trois options spécifiées dans l'énumération. Ainsi, vous ne pouvez pas attribuer quelque chose de manière incorrecte par accident ou créer facilement des bogues de cette façon.
Si vous essayez d'utiliser une autre variable, cela générera une erreur de type comme celle-ci :
enum Door {
Open = "open",
Closed = "closed",
Ajar = "ajar" // half open, half closed
}
console.log(Door.FulyOpened)
Property 'FullyOpened' does not exist on type 'typeof Door'.
L'extension est l'un des quatre piliers de l'orientation objet et est une fonctionnalité de langage présente dans TypeScript. L'extension d'une énumération vous permet essentiellement de copier une définition de variable et d'y ajouter quelque chose de plus.
Ainsi, par exemple, vous pourriez essayer de faire quelque chose comme ceci :
enum Door {
Open = "open",
Closed = "closed",
Ajar = "ajar" // half open, half closed
}
enum DoorFrame extends Door { // This will not work!
Missing = "noDoor"
}
console.log(DoorFrame.Missing)
Nous pourrions ensuite ajouter des propriétés supplémentaires dans une énumération, ou même fusionner deux énumérations ensemble, pour toujours obtenir un typage strict sur notre énumération tout en pouvant les modifier une fois qu'elles ont été définies.
Mais notez que l'extrait de code ci-dessus ne fonctionne pas ! Il ne parvient pas à transpiler et génère quatre erreurs différentes.
La réponse courte est non, vous ne pouvez pas étendre les énumérations car TypeScript n'offre aucune fonctionnalité de langage pour les étendre. Cependant, il existe des solutions de contournement que vous pouvez utiliser pour obtenir ce que l'héritage ferait.
enum Door {
Open = "open",
Closed = "closed",
Ajar = "ajar" // half open, half closed
}
enum DoorFrame {
Missing = "noDoor"
}
type DoorState = Door | DoorFrame;
Dans le bloc de code ci-dessus, nous avons utilisé un type d'intersection . L'intersection agit comme un « ou », ce qui signifie simplement que le DoorState
type sera soit de type Door
soit de type DoorFrame
.
Cela signifie maintenant que DoorState
vous pouvez utiliser l'une ou l'autre des variables des deux énumérations de manière interchangeable.
Nous avons vu précédemment dans le code transpilé qu'une énumération devient un objet JavaScript, avec les clés et les valeurs que votre énumération spécifie.
En TypeScript, nous pourrions écrire purement JavaScript si nous le voulions. En fait, c'est une grande force de TypeScript. Vous pouvez, par exemple, renommer tous vos file.js
to file.ts
et désactiver les vérifications du compilateur pour votre code. Tant que vous exécutez les étapes de compilation/transpilation, tout fonctionnera correctement, sans aucun changement de code.
Nous pouvons en faire usage en sachant que lorsque notre énumération se transformera en JavaScript, ce sera un littéral d'objet JavaScript et utilisera la syntaxe de propagation, comme ci-dessous :
enum Move {
LEFT = 'Left',
RIGHT = 'Right',
FORWARD = 'Forward',
BACKWARD = 'Backward'
}
const myMove = {
...Move,
JUMP: 'Jump'
}
Cette solution a été décrite en second lieu, cependant, car elle n'est pas aussi bonne que le type d'intersection car elle n'est pas aussi robuste que notre première solution. En effet, la "composition" de votre énumération se produit au moment de l'exécution, alors que lorsque nous utilisons l'intersection de types, la vérification de type peut se produire au moment de la compilation/transpilation, pas au moment de l'exécution.
Nous avons discuté de la manière dont nous pouvons étendre les énumérations dans Typescript, mais les énumérations ne sont pas une solution miracle à utiliser pour résoudre tous les problèmes. Les énumérations, lorsqu'elles sont utilisées de manière incorrecte, peuvent aggraver la lisibilité, l'évolutivité et la maintenabilité de votre code, au lieu d'améliorer votre code.
Alors, couvrons quelques bonnes pratiques et modèles courants à utiliser lorsque vous travaillez avec des énumérations dans TypeScript.
J'ai expliqué comment nous pouvons avoir des énumérations de chaînes comme celle-ci:
enum Seasons {
Summer = "Summer",
Winter = "Winter",
Spring = "Spring",
Fall = "Fall"
}
En plus d'avoir également des énumérations numériques comme celle-ci :
enum Decision {
Yes,
No
}
Mais, il existe un troisième type d'énumération, dont vous ne connaissez peut-être pas l'existence, appelée énumération hétérogène . C'est ici que vous pouvez utiliser une chaîne et des énumérations numériques dans la même énumération.
Un exemple tiré de la documentation est celui-ci :
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
Il est important de noter que même la documentation décourage cette pratique, car dans ce cas, l'utilisation de cette méthode indique que vous devez probablement :
Parfois, la fonctionnalité de code peut être forcée d'adhérer à une option enum, qui peut rapidement se transformer en un anti-modèle.
Voici un exemple :
enum Operators {
Add,
Subtract
}
function calculate(op: Operators, firstNumber: number, secondNumber: number) {
switch(op) {
case Operators.Add: return firstNumber + secondNumber
case Operators.Subtract: return firstNumber - secondNumber
}
}
Le code ci-dessus semble assez simple et sûr, car notre exemple est, en effet, simple et sûr.
Mais dans les bases de code volumineuses, lorsque vous liez strictement les détails d'implémentation à des types d'énumération comme celui-ci, vous pouvez causer quelques problèmes :
Si vous devez faire quelque chose comme ci-dessus, un modèle plus simple (et plus condensé) pourrait ressembler à ceci.
const Operators = {
Add: {
id: 0,
apply(firstNumber: number, secondNumber: number) { return firstNumber + secondNumber }
},
Subtract: {
id: 1,
apply(firstNumber: number, secondNumber: number) { return firstNumber - secondNumber }
}
}
Vous pouvez en savoir plus sur ce modèle ici ou ici .
Il existe un moyen de regrouper généralement différents types de données utilisées dans le code : variables discrètes ou variables continues.
Les variables discrètes sont des données qui ont des espaces entre leurs représentations et qui n'ont que quelques représentations. Voici quelques exemples:
Les données discrètes sont un bon candidat pour être placées dans une énumération, et elles peuvent aider à la clarté et à la réutilisation du code. Les données continues font référence à des données sans lacunes qui tombent dans une séquence continue, comme des nombres. Celles-ci peuvent être différentes selon leur mesure :
Les données discrètes sont un bon candidat pour les données, et elles peuvent être utilisées dans une énumération, alors que les données continues ne doivent pas être utilisées dans une énumération. Pouvez-vous imaginer une énumération pour l'âge ?
enum Age {
Zero,
One,
Two,
Three,
Four,
Five,
Six
}
Ce n'est pas un bon candidat pour être placé dans une énumération car il devra être continuellement mis à jour et modifié, ce qui entraînera un cauchemar de maintenance.
Vous ne devriez chercher qu'à ajouter des types de données discrets et hautement stables à l'intérieur d'une énumération.
J'espère que cet article vous a été utile pour mieux comprendre ce que sont les énumérations, les problèmes qu'elles résolvent, les cas d'utilisation pour fusionner deux énumérations et comment vous pourriez y parvenir ! Bon piratage.
Source : https://blog.logrocket.com/extend-enums-typescript/
1660113420
Voici un bref aperçu des fonctions dans TypeScript. 💁♂️
Les paramètres doivent toujours être suivis d'annotations de type. L'exception à cette règle concerne les valeurs par défaut, car TypeScript est capable de déduire le type à partir des valeurs elles-mêmes. Un paramètre est-il facultatif ? Marquez-le avec un ?
ou bien votre linter lancera une erreur lors de l'appel de la fonction.
function printName(firstName: string, lastName = 'Smith', middleName?: string) {
if (middleName) console.log(firstName, middleName, lastName)
else console.log(firstName, lastName)
}
Bien que TypeScript puisse déduire le type de retour d'une fonction , il est recommandé 👍 de l'indiquer explicitement car il sert de forme d'auto-documentation. L'annotation de type est écrite après les parenthèses et avant le corps de la fonction.
Si la fonction ne renvoie rien, le type void
est utilisé.
function getNumber(): number { return 6 }
function sayHello(): void { console.log('Hello!') }
Dans les fonctions fléchées, les annotations de type suivent la même syntaxe que dans les déclarations de fonction.
const isNumber5 = (value: number): boolean => value === 5
Source : https://dilshankelsen.com/define-functions-in-typescript/