Comment utiliser les fonctions dans TypeScript

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.

Rien de nouveau, juste plus sûr ?

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.

Types de paramètres

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'.

Paramètres facultatifs

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.

Paramètres par défaut

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
}

Paramètres de repos

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'.

Types de retour

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'.

Types de fonctions

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
}

Types de fonctions avec types et interfaces

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 typemot-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

Conclusion:

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.

What is GEEK

Buddha Community

The Definitive Guide to TypeScript & Possibly The Best TypeScript Book

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 🌹

Reviews

  • Thanks for the wonderful book. Learned a lot from it. (link)
  • Its probably the Best TypeScript book out there. Good Job (link)
  • Love how precise and clear the examples and explanations are! (link)
  • For the low, low price of free, you get pages of pure awesomeness. Chock full of source code examples and clear, concise explanations, TypeScript Deep Dive will help you learn TypeScript development. (link)
  • Just a big thank you! Best TypeScript 2 detailed explanation! (link)
  • This gitbook got my project going pronto. Fluent easy read 5 stars. (link)
  • I recommend the online #typescript book by @basarat you'll love it.(link)
  • I've always found this by @basarat really helpful. (link)
  • We must highlight TypeScript Deep Dive, an open source book.(link)
  • Great online resource for learning. (link)
  • Thank you for putting this book together, and for all your hard work within the TypeScript community. (link)
  • TypeScript Deep Dive is one of the best technical texts I've read in a while. (link)
  • Thanks @basarat for the TypeScript Deep Dive Book. Help me a lot with my first TypeScript project. (link)
  • Thanks to @basarat for this great #typescript learning resource. (link)
  • Guyz excellent book on Typescript(@typescriptlang) by @basarat (link)
  • Leaning on the legendary @basarat's "TypeScript Deep Dive" book heavily at the moment (link)
  • numTimesPointedPeopleToBasaratsTypeScriptBook++; (link)
  • A book not only for typescript, a good one for deeper JavaScript knowledge as well. link
  • In my new job, we're using @typescriptlang, which I am new to. This is insanely helpful huge thanks, @basarat! link
  • Thank you for writing TypeScript Deep Dive. I have learned so much. link
  • Loving @basarat's @typescriptlang online book basarat.gitbooks.io/typescript/# loaded with great recipes! link
  • Microsoft doc is great already, but if want to "dig deeper" into TypeScript I find this book of great value link
  • Thanks, this is a great book 🤓🤓 link
  • Deep dive to typescript is awesome in so many levels. i find it very insightful. Thanks link
  • @basarat's intro to @typescriptlang is still one of the best going (if not THE best) link
  •  
  • This is sweet! So many #typescript goodies! link

Get Started

If you are here to read the book online get started.

Translations

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.

Other Options

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.

Special Thanks

All the amazing contributors 🌹

Share

Share URL: https://basarat.gitbook.io/typescript/

Author: Basarat
Source Code: https://github.com/basarat/typescript-book/ 
License: View license

#typescript #opensource 

Comment utiliser les fonctions dans TypeScript

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.

Rien de nouveau, juste plus sûr ?

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.

Types de paramètres

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'.

Paramètres facultatifs

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.

Paramètres par défaut

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
}

Paramètres de repos

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'.

Types de retour

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'.

Types de fonctions

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
}

Types de fonctions avec types et interfaces

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 typemot-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

Conclusion:

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.

Léon  Peltier

Léon Peltier

1657590960

Comment Utiliser Pick Dans TypeScript

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 Typepuis déclarons le Keysque nous souhaitons "choisir" dans le Type. Avoir du sens ? Ils Keys doivent exister sur le Typepour 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- typeclé, 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 typemonde de douleur.

C'est là Pickqu'entre en jeu. Je vise un code minimal. Aucun code n'est un bon code !

Comme nous avons déjà examiné la syntaxe, Pickaccepte un existant Type, puis les propriétés ( Keys) que vous souhaitez "choisir" à partir de celui-ci.

Commençons par créer un Credentialstype via an interface, qui remplacera notre pile de typedéclarations et introduira un peu Pickde 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 interfacea plutôt que a typesauf si je compose des types plus complexes , ce qui, à mon avis, n'est pas particulièrement complexe.

À l' aide Pickde , nous pouvons dire à TypeScript de choisir ceux qui sont particuliers Keysparmi nos existants Type(qui pourraient être un interfaceou 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- typeclé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 ».Icône de téléchargement

Si nous devions à l'avenir modifier l' Credentialsinterface, les nouvelles définitions circuleront dans le reste du code, plutôt que de mettre à jour manuellement chaque type d'intersection.

Pickest 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 Picktypes 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 interfaceau 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

#typescript 

Comment Étendre Les Énumérations Dans TypeScript

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. 

Que sont les énumérations dans 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, 1et 2comme 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'.

Pourquoi avons-nous besoin d'étendre une énumération ?

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.

Pouvez-vous étendre les énumérations ?

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.

Intersection de type dans TypeScript

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 DoorStatetype sera soit de type Doorsoit de type DoorFrame.

Cela signifie maintenant que DoorStatevous pouvez utiliser l'une ou l'autre des variables des deux énumérations de manière interchangeable.

Syntaxe de diffusion

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.jsto file.tset 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.

Meilleures pratiques d'énumération TypeScript

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.

1. Éviter les énumérations hétérogènes

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 :

  • Reconsidérer la relation entre ces deux variables
  • Créer deux énumérations distinctes
  • Rendez-les tous deux conformes à un type de données

2. L'anti-pattern "enums as configuration"

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 :

  • Vous créez deux sources de vérité (l'énumération et la fonction doivent être mises à jour si l'énumération change)
  • Ce modèle va diffuser des métadonnées autour du code
  • Le bloc de code n'est plus générique

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 .

3. Les types de données que les énumérations représentent le mieux

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:

  • Jours de la semaine
    • Lun
    • Mar
    • Épouser
    • Jeu
    • Ven
    • Assis
    • Soleil
  • Saisons
    • Été
    • L'hiver
    • Le printemps
    • Tomber

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 :

  • Le poids de quelqu'un
  • La vitesse d'une voiture

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.

Conclusion

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/ 

#typescript 

Anne  de Morel

Anne de Morel

1660113420

Comment Définir Des Fonctions Dans TypeScript

Voici un bref aperçu des fonctions dans TypeScript. 💁‍♂️

Paramètres

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) 
}

Valeur de retour

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 voidest utilisé.

function getNumber(): number { return 6 }
function sayHello(): void { console.log('Hello!') }

Fonctions fléchées

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/

#typescript