[{"data":1,"prerenderedAt":1162},["ShallowReactive",2],{"page-\u002Fts\u002Fgeneriques-et-utilitaires":3,"pieces-ts":1119,"autour-\u002Fts\u002Fgeneriques-et-utilitaires":1144,"prerequis-\u002Fts\u002Fgeneriques-et-utilitaires":1149,"plan-ts":1151},{"id":4,"title":5,"body":6,"description":1090,"extension":1091,"ligne":56,"meta":1092,"motsCles":1093,"navigation":124,"niveau":1095,"path":1096,"prerequis":1097,"ressources":1099,"seo":1111,"sources":1112,"stem":1117,"__hash__":1118},"docs\u002Fts\u002F05.generiques-et-utilitaires.md","Génériques et types utilitaires",{"type":7,"value":8,"toc":1077},"minimark",[9,14,32,36,44,51,164,167,171,179,289,294,301,305,311,431,443,447,450,523,532,536,543,546,603,607,613,690,701,705,715,772,793,800,804,810,905,912,916,1007,1021,1025,1073],[10,11,13],"h2",{"id":12},"ce-que-tu-vas-apprendre","Ce que tu vas apprendre",[15,16,17,21,29],"ul",{},[18,19,20],"li",{},"Écrire une fonction et un type génériques.",[18,22,23,24,28],{},"Contraindre un générique avec ",[25,26,27],"code",{},"extends",".",[18,30,31],{},"Dériver de nouveaux types avec les types utilitaires.",[10,33,35],{"id":34},"le-besoin-une-fonction-pour-tous-les-types","Le besoin : une fonction pour tous les types",[37,38,39,40,43],"p",{},"Imagine une fonction qui renvoie le premier élément d'une liste. Pour des textes, tu écris ",[25,41,42],{},"string[]",". Pour des nombres, il faudrait une seconde fonction.",[37,45,46,47,50],{},"Sans générique, tu es tenté par ",[25,48,49],{},"any"," :",[52,53,58],"pre",{"className":54,"code":55,"language":56,"meta":57,"style":57},"language-ts shiki shiki-themes github-light-default github-dark-default github-dark-default","function premier(liste: any[]): any {\n  return liste[0]\n}\n\nconst x = premier([1, 2, 3]) \u002F\u002F any : on a perdu le type\n","ts","",[25,59,60,98,113,119,126],{"__ignoreMap":57},[61,62,65,69,73,77,81,84,88,91,93,95],"span",{"class":63,"line":64},"line",1,[61,66,68],{"class":67},"sOnC1","function",[61,70,72],{"class":71},"syCW7"," premier",[61,74,76],{"class":75},"scfrF","(",[61,78,80],{"class":79},"sIXEE","liste",[61,82,83],{"class":67},":",[61,85,87],{"class":86},"s5iOY"," any",[61,89,90],{"class":75},"[])",[61,92,83],{"class":67},[61,94,87],{"class":86},[61,96,97],{"class":75}," {\n",[61,99,101,104,107,110],{"class":63,"line":100},2,[61,102,103],{"class":67},"  return",[61,105,106],{"class":75}," liste[",[61,108,109],{"class":86},"0",[61,111,112],{"class":75},"]\n",[61,114,116],{"class":63,"line":115},3,[61,117,118],{"class":75},"}\n",[61,120,122],{"class":63,"line":121},4,[61,123,125],{"emptyLinePlaceholder":124},true,"\n",[61,127,129,132,135,138,140,143,146,149,152,154,157,160],{"class":63,"line":128},5,[61,130,131],{"class":67},"const",[61,133,134],{"class":86}," x",[61,136,137],{"class":67}," =",[61,139,72],{"class":71},[61,141,142],{"class":75},"([",[61,144,145],{"class":86},"1",[61,147,148],{"class":75},", ",[61,150,151],{"class":86},"2",[61,153,148],{"class":75},[61,155,156],{"class":86},"3",[61,158,159],{"class":75},"]) ",[61,161,163],{"class":162},"sd6ml","\u002F\u002F any : on a perdu le type\n",[37,165,166],{},"Le résultat n'est plus vérifié. Un générique garde le lien entre l'entrée et la sortie.",[10,168,170],{"id":169},"un-générique-cest-un-type-en-paramètre","Un générique, c'est un type en paramètre",[37,172,173,174,178],{},"Un ",[175,176,177],"strong",{},"générique"," est un type que tu laisses en paramètre, comme tu laisses une valeur en paramètre d'une fonction. On le note entre chevrons.",[52,180,182],{"className":54,"code":181,"language":56,"meta":57,"style":57},"function premier\u003CT>(liste: T[]): T {\n  return liste[0]\n}\n\nconst a = premier([\"ail\", \"sel\"]) \u002F\u002F string\nconst b = premier([1, 2, 3])      \u002F\u002F number\n",[25,183,184,214,224,228,232,259],{"__ignoreMap":57},[61,185,186,188,190,193,196,199,201,203,206,208,210,212],{"class":63,"line":64},[61,187,68],{"class":67},[61,189,72],{"class":71},[61,191,192],{"class":75},"\u003C",[61,194,195],{"class":79},"T",[61,197,198],{"class":75},">(",[61,200,80],{"class":79},[61,202,83],{"class":67},[61,204,205],{"class":79}," T",[61,207,90],{"class":75},[61,209,83],{"class":67},[61,211,205],{"class":79},[61,213,97],{"class":75},[61,215,216,218,220,222],{"class":63,"line":100},[61,217,103],{"class":67},[61,219,106],{"class":75},[61,221,109],{"class":86},[61,223,112],{"class":75},[61,225,226],{"class":63,"line":115},[61,227,118],{"class":75},[61,229,230],{"class":63,"line":121},[61,231,125],{"emptyLinePlaceholder":124},[61,233,234,236,239,241,243,245,249,251,254,256],{"class":63,"line":128},[61,235,131],{"class":67},[61,237,238],{"class":86}," a",[61,240,137],{"class":67},[61,242,72],{"class":71},[61,244,142],{"class":75},[61,246,248],{"class":247},"shWOn","\"ail\"",[61,250,148],{"class":75},[61,252,253],{"class":247},"\"sel\"",[61,255,159],{"class":75},[61,257,258],{"class":162},"\u002F\u002F string\n",[61,260,262,264,267,269,271,273,275,277,279,281,283,286],{"class":63,"line":261},6,[61,263,131],{"class":67},[61,265,266],{"class":86}," b",[61,268,137],{"class":67},[61,270,72],{"class":71},[61,272,142],{"class":75},[61,274,145],{"class":86},[61,276,148],{"class":75},[61,278,151],{"class":86},[61,280,148],{"class":75},[61,282,156],{"class":86},[61,284,285],{"class":75},"])      ",[61,287,288],{"class":162},"\u002F\u002F number\n",[37,290,291,293],{},[25,292,195],{}," est un nom d'usage pour « un type à préciser ». TypeScript le déduit à chaque appel d'après les arguments.",[37,295,296,297,300],{},"Tu peux aussi le donner toi-même : ",[25,298,299],{},"premier\u003Cstring>([\"ail\", \"sel\"])",". En général, l'inférence suffit.",[10,302,304],{"id":303},"contraindre-un-générique","Contraindre un générique",[37,306,307,308,310],{},"Parfois le type doit avoir une certaine forme. Le mot ",[175,309,27],{}," pose une condition.",[52,312,314],{"className":54,"code":313,"language":56,"meta":57,"style":57},"function nomsDe\u003CT extends { nom: string }>(elements: T[]): string[] {\n  return elements.map((element) => element.nom)\n}\n\nnomsDe([{ nom: \"Crêpes\", duree: 20 }]) \u002F\u002F accepté\nnomsDe([{ duree: 20 }])                \u002F\u002F Erreur\n",[25,315,316,360,385,389,393,416],{"__ignoreMap":57},[61,317,318,320,323,325,327,330,333,336,338,341,344,347,349,351,353,355,357],{"class":63,"line":64},[61,319,68],{"class":67},[61,321,322],{"class":71}," nomsDe",[61,324,192],{"class":75},[61,326,195],{"class":79},[61,328,329],{"class":67}," extends",[61,331,332],{"class":75}," { ",[61,334,335],{"class":79},"nom",[61,337,83],{"class":67},[61,339,340],{"class":86}," string",[61,342,343],{"class":75}," }>(",[61,345,346],{"class":79},"elements",[61,348,83],{"class":67},[61,350,205],{"class":79},[61,352,90],{"class":75},[61,354,83],{"class":67},[61,356,340],{"class":86},[61,358,359],{"class":75},"[] {\n",[61,361,362,364,367,370,373,376,379,382],{"class":63,"line":100},[61,363,103],{"class":67},[61,365,366],{"class":75}," elements.",[61,368,369],{"class":71},"map",[61,371,372],{"class":75},"((",[61,374,375],{"class":79},"element",[61,377,378],{"class":75},") ",[61,380,381],{"class":67},"=>",[61,383,384],{"class":75}," element.nom)\n",[61,386,387],{"class":63,"line":115},[61,388,118],{"class":75},[61,390,391],{"class":63,"line":121},[61,392,125],{"emptyLinePlaceholder":124},[61,394,395,398,401,404,407,410,413],{"class":63,"line":128},[61,396,397],{"class":71},"nomsDe",[61,399,400],{"class":75},"([{ nom: ",[61,402,403],{"class":247},"\"Crêpes\"",[61,405,406],{"class":75},", duree: ",[61,408,409],{"class":86},"20",[61,411,412],{"class":75}," }]) ",[61,414,415],{"class":162},"\u002F\u002F accepté\n",[61,417,418,420,423,425,428],{"class":63,"line":261},[61,419,397],{"class":71},[61,421,422],{"class":75},"([{ duree: ",[61,424,409],{"class":86},[61,426,427],{"class":75}," }])                ",[61,429,430],{"class":162},"\u002F\u002F Erreur\n",[37,432,433,435,436,438,439,442],{},[25,434,195],{}," peut être n'importe quel type, à condition d'avoir une propriété ",[25,437,335],{}," de type texte. Dans la fonction, tu peux donc lire ",[25,440,441],{},"element.nom"," sans risque.",[10,444,446],{"id":445},"un-type-générique","Un type générique",[37,448,449],{},"Les interfaces et les alias acceptent aussi des paramètres de type.",[52,451,453],{"className":54,"code":452,"language":56,"meta":57,"style":57},"interface Reponse\u003CT> {\n  donnees: T\n  erreur: string | null\n}\n\ntype ReponseRecettes = Reponse\u003CRecette[]>\n",[25,454,455,470,480,495,499,503],{"__ignoreMap":57},[61,456,457,460,463,465,467],{"class":63,"line":64},[61,458,459],{"class":67},"interface",[61,461,462],{"class":79}," Reponse",[61,464,192],{"class":75},[61,466,195],{"class":79},[61,468,469],{"class":75},"> {\n",[61,471,472,475,477],{"class":63,"line":100},[61,473,474],{"class":79},"  donnees",[61,476,83],{"class":67},[61,478,479],{"class":79}," T\n",[61,481,482,485,487,489,492],{"class":63,"line":115},[61,483,484],{"class":79},"  erreur",[61,486,83],{"class":67},[61,488,340],{"class":86},[61,490,491],{"class":67}," |",[61,493,494],{"class":86}," null\n",[61,496,497],{"class":63,"line":121},[61,498,118],{"class":75},[61,500,501],{"class":63,"line":128},[61,502,125],{"emptyLinePlaceholder":124},[61,504,505,508,511,513,515,517,520],{"class":63,"line":261},[61,506,507],{"class":67},"type",[61,509,510],{"class":79}," ReponseRecettes",[61,512,137],{"class":67},[61,514,462],{"class":79},[61,516,192],{"class":75},[61,518,519],{"class":79},"Recette",[61,521,522],{"class":75},"[]>\n",[37,524,525,526,529,530,28],{},"Une même structure sert à toutes tes réponses d'API : tu précises seulement le contenu. Tu as déjà rencontré cette notation avec ",[25,527,528],{},"Array\u003Cstring>",", équivalent de ",[25,531,42],{},[10,533,535],{"id":534},"les-types-utilitaires","Les types utilitaires",[37,537,538,539,542],{},"TypeScript fournit des ",[175,540,541],{},"types utilitaires"," : des outils qui transforment un type existant en un autre. Ils évitent de recopier des interfaces entières.",[37,544,545],{},"Voici l'interface de départ :",[52,547,549],{"className":54,"code":548,"language":56,"meta":57,"style":57},"interface Recette {\n  id: number\n  nom: string\n  duree: number\n  vegetarien: boolean\n}\n",[25,550,551,560,570,580,589,599],{"__ignoreMap":57},[61,552,553,555,558],{"class":63,"line":64},[61,554,459],{"class":67},[61,556,557],{"class":79}," Recette",[61,559,97],{"class":75},[61,561,562,565,567],{"class":63,"line":100},[61,563,564],{"class":79},"  id",[61,566,83],{"class":67},[61,568,569],{"class":86}," number\n",[61,571,572,575,577],{"class":63,"line":115},[61,573,574],{"class":79},"  nom",[61,576,83],{"class":67},[61,578,579],{"class":86}," string\n",[61,581,582,585,587],{"class":63,"line":121},[61,583,584],{"class":79},"  duree",[61,586,83],{"class":67},[61,588,569],{"class":86},[61,590,591,594,596],{"class":63,"line":128},[61,592,593],{"class":79},"  vegetarien",[61,595,83],{"class":67},[61,597,598],{"class":86}," boolean\n",[61,600,601],{"class":63,"line":261},[61,602,118],{"class":75},[10,604,606],{"id":605},"partial-tout-devient-optionnel","Partial : tout devient optionnel",[37,608,609,612],{},[25,610,611],{},"Partial\u003CRecette>"," rend toutes les propriétés facultatives. C'est pratique pour une mise à jour partielle.",[52,614,616],{"className":54,"code":615,"language":56,"meta":57,"style":57},"function modifier(recette: Recette, changements: Partial\u003CRecette>) {\n  return { ...recette, ...changements }\n}\n\nmodifier(gratin, { duree: 50 })\n",[25,617,618,651,668,672,676],{"__ignoreMap":57},[61,619,620,622,625,627,630,632,634,636,639,641,644,646,648],{"class":63,"line":64},[61,621,68],{"class":67},[61,623,624],{"class":71}," modifier",[61,626,76],{"class":75},[61,628,629],{"class":79},"recette",[61,631,83],{"class":67},[61,633,557],{"class":79},[61,635,148],{"class":75},[61,637,638],{"class":79},"changements",[61,640,83],{"class":67},[61,642,643],{"class":79}," Partial",[61,645,192],{"class":75},[61,647,519],{"class":79},[61,649,650],{"class":75},">) {\n",[61,652,653,655,657,660,663,665],{"class":63,"line":100},[61,654,103],{"class":67},[61,656,332],{"class":75},[61,658,659],{"class":67},"...",[61,661,662],{"class":75},"recette, ",[61,664,659],{"class":67},[61,666,667],{"class":75},"changements }\n",[61,669,670],{"class":63,"line":115},[61,671,118],{"class":75},[61,673,674],{"class":63,"line":121},[61,675,125],{"emptyLinePlaceholder":124},[61,677,678,681,684,687],{"class":63,"line":128},[61,679,680],{"class":71},"modifier",[61,682,683],{"class":75},"(gratin, { duree: ",[61,685,686],{"class":86},"50",[61,688,689],{"class":75}," })\n",[37,691,692,693,696,697,700],{},"Tu n'envoies que les champs qui changent. ",[25,694,695],{},"Required\u003CRecette>"," fait l'inverse, ",[25,698,699],{},"Readonly\u003CRecette>"," interdit les modifications.",[10,702,704],{"id":703},"pick-et-omit-garder-ou-retirer","Pick et Omit : garder ou retirer",[37,706,707,710,711,714],{},[25,708,709],{},"Pick"," conserve les propriétés listées. ",[25,712,713],{},"Omit"," retire celles que tu indiques.",[52,716,718],{"className":54,"code":717,"language":56,"meta":57,"style":57},"type Apercu = Pick\u003CRecette, \"nom\" | \"duree\">\ntype NouvelleRecette = Omit\u003CRecette, \"id\">\n",[25,719,720,749],{"__ignoreMap":57},[61,721,722,724,727,729,732,734,736,738,741,743,746],{"class":63,"line":64},[61,723,507],{"class":67},[61,725,726],{"class":79}," Apercu",[61,728,137],{"class":67},[61,730,731],{"class":79}," Pick",[61,733,192],{"class":75},[61,735,519],{"class":79},[61,737,148],{"class":75},[61,739,740],{"class":247},"\"nom\"",[61,742,491],{"class":67},[61,744,745],{"class":247}," \"duree\"",[61,747,748],{"class":75},">\n",[61,750,751,753,756,758,761,763,765,767,770],{"class":63,"line":100},[61,752,507],{"class":67},[61,754,755],{"class":79}," NouvelleRecette",[61,757,137],{"class":67},[61,759,760],{"class":79}," Omit",[61,762,192],{"class":75},[61,764,519],{"class":79},[61,766,148],{"class":75},[61,768,769],{"class":247},"\"id\"",[61,771,748],{"class":75},[37,773,774,777,778,780,781,784,785,788,789,792],{},[25,775,776],{},"Apercu"," n'a que ",[25,779,335],{}," et ",[25,782,783],{},"duree",". ",[25,786,787],{},"NouvelleRecette"," possède tout sauf ",[25,790,791],{},"id",", ce qui convient à un formulaire de création, car l'identifiant est attribué après coup.",[37,794,795,796,799],{},"Les clés sont écrites comme des types littéraux, séparés par ",[25,797,798],{},"|",". Une faute de frappe dans un nom est signalée.",[10,801,803],{"id":802},"record-un-dictionnaire","Record : un dictionnaire",[37,805,806,809],{},[25,807,808],{},"Record\u003CCles, Valeur>"," décrit un objet dont les clés et les valeurs ont les types donnés.",[52,811,813],{"className":54,"code":812,"language":56,"meta":57,"style":57},"type Difficulte = \"facile\" | \"moyen\" | \"difficile\"\n\nconst couleurs: Record\u003CDifficulte, string> = {\n  facile: \"vert\",\n  moyen: \"orange\",\n  difficile: \"rouge\"\n}\n",[25,814,815,837,841,871,882,892,900],{"__ignoreMap":57},[61,816,817,819,822,824,827,829,832,834],{"class":63,"line":64},[61,818,507],{"class":67},[61,820,821],{"class":79}," Difficulte",[61,823,137],{"class":67},[61,825,826],{"class":247}," \"facile\"",[61,828,491],{"class":67},[61,830,831],{"class":247}," \"moyen\"",[61,833,491],{"class":67},[61,835,836],{"class":247}," \"difficile\"\n",[61,838,839],{"class":63,"line":100},[61,840,125],{"emptyLinePlaceholder":124},[61,842,843,845,848,850,853,855,858,860,863,866,869],{"class":63,"line":115},[61,844,131],{"class":67},[61,846,847],{"class":86}," couleurs",[61,849,83],{"class":67},[61,851,852],{"class":79}," Record",[61,854,192],{"class":75},[61,856,857],{"class":79},"Difficulte",[61,859,148],{"class":75},[61,861,862],{"class":86},"string",[61,864,865],{"class":75},"> ",[61,867,868],{"class":67},"=",[61,870,97],{"class":75},[61,872,873,876,879],{"class":63,"line":121},[61,874,875],{"class":75},"  facile: ",[61,877,878],{"class":247},"\"vert\"",[61,880,881],{"class":75},",\n",[61,883,884,887,890],{"class":63,"line":128},[61,885,886],{"class":75},"  moyen: ",[61,888,889],{"class":247},"\"orange\"",[61,891,881],{"class":75},[61,893,894,897],{"class":63,"line":261},[61,895,896],{"class":75},"  difficile: ",[61,898,899],{"class":247},"\"rouge\"\n",[61,901,903],{"class":63,"line":902},7,[61,904,118],{"class":75},[37,906,907,908,911],{},"Si tu oublies une des trois clés, TypeScript le signale. ",[25,909,910],{},"Record\u003Cstring, number>"," convient à un objet dont les clés ne sont pas connues d'avance.",[10,913,915],{"id":914},"récapitulatif-des-utilitaires","Récapitulatif des utilitaires",[917,918,919,932],"table",{},[920,921,922],"thead",{},[923,924,925,929],"tr",{},[926,927,928],"th",{},"Type",[926,930,931],{},"Effet",[933,934,935,946,956,966,979,991],"tbody",{},[923,936,937,943],{},[938,939,940],"td",{},[25,941,942],{},"Partial\u003CT>",[938,944,945],{},"Toutes les propriétés deviennent facultatives",[923,947,948,953],{},[938,949,950],{},[25,951,952],{},"Required\u003CT>",[938,954,955],{},"Toutes les propriétés deviennent obligatoires",[923,957,958,963],{},[938,959,960],{},[25,961,962],{},"Readonly\u003CT>",[938,964,965],{},"Toutes les propriétés passent en lecture seule",[923,967,968,973],{},[938,969,970],{},[25,971,972],{},"Pick\u003CT, K>",[938,974,975,976],{},"Garde seulement les clés ",[25,977,978],{},"K",[923,980,981,986],{},[938,982,983],{},[25,984,985],{},"Omit\u003CT, K>",[938,987,988,989],{},"Retire les clés ",[25,990,978],{},[923,992,993,998],{},[938,994,995],{},[25,996,997],{},"Record\u003CK, V>",[938,999,1000,1001,1003,1004],{},"Crée un objet de clés ",[25,1002,978],{}," et de valeurs ",[25,1005,1006],{},"V",[1008,1009,1010],"tip",{},[37,1011,1012,1013,1015,1016,780,1018,1020],{},"Dérive tes types plutôt que de les copier. Si ",[25,1014,519],{}," change, ",[25,1017,776],{},[25,1019,787],{}," suivent sans que tu y touches.",[10,1022,1024],{"id":1023},"à-retenir","À retenir",[15,1026,1027,1034,1040,1046,1058,1070],{},[18,1028,1029,1030,1033],{},"Un générique ",[25,1031,1032],{},"\u003CT>"," est un type passé en paramètre, déduit à l'appel.",[18,1035,1036,1037,1039],{},"Il garde le lien entre l'entrée et la sortie, là où ",[25,1038,49],{}," le perd.",[18,1041,1042,1045],{},[25,1043,1044],{},"T extends { nom: string }"," impose une forme minimale.",[18,1047,1048,148,1051,780,1054,1057],{},[25,1049,1050],{},"Partial",[25,1052,1053],{},"Required",[25,1055,1056],{},"Readonly"," modifient toutes les propriétés d'un type.",[18,1059,1060,1062,1063,1065,1066,1069],{},[25,1061,709],{}," garde des clés, ",[25,1064,713],{}," en retire, ",[25,1067,1068],{},"Record"," fabrique un dictionnaire.",[18,1071,1072],{},"Dériver un type évite de dupliquer ses propriétés.",[1074,1075,1076],"style",{},"html pre.shiki code .sOnC1, html code.shiki .sOnC1{--shiki-light:#CF222E;--shiki-default:#FF7B72;--shiki-dark:#FF7B72}html pre.shiki code .syCW7, html code.shiki .syCW7{--shiki-light:#8250DF;--shiki-default:#D2A8FF;--shiki-dark:#D2A8FF}html pre.shiki code .scfrF, html code.shiki .scfrF{--shiki-light:#1F2328;--shiki-default:#E6EDF3;--shiki-dark:#E6EDF3}html pre.shiki code .sIXEE, html code.shiki .sIXEE{--shiki-light:#953800;--shiki-default:#FFA657;--shiki-dark:#FFA657}html pre.shiki code .s5iOY, html code.shiki .s5iOY{--shiki-light:#0550AE;--shiki-default:#79C0FF;--shiki-dark:#79C0FF}html pre.shiki code .sd6ml, html code.shiki .sd6ml{--shiki-light:#6E7781;--shiki-default:#8B949E;--shiki-dark:#8B949E}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .shWOn, html code.shiki .shWOn{--shiki-light:#0A3069;--shiki-default:#A5D6FF;--shiki-dark:#A5D6FF}",{"title":57,"searchDepth":100,"depth":115,"links":1078},[1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089],{"id":12,"depth":100,"text":13},{"id":34,"depth":100,"text":35},{"id":169,"depth":100,"text":170},{"id":303,"depth":100,"text":304},{"id":445,"depth":100,"text":446},{"id":534,"depth":100,"text":535},{"id":605,"depth":100,"text":606},{"id":703,"depth":100,"text":704},{"id":802,"depth":100,"text":803},{"id":914,"depth":100,"text":915},{"id":1023,"depth":100,"text":1024},"Écris des fonctions et des types réutilisables avec les génériques, puis dérive des types avec Partial, Pick, Omit et Record.","md",{},[177,1094,27,1050,1053,1056,709,713,1068],"paramètre de type","intermediaire","\u002Fts\u002Fgeneriques-et-utilitaires",[1098],"\u002Fts\u002Funions-et-narrowing",[1100,1104,1108],{"nom":1101,"url":1102,"type":1103},"Grafikart, formation TypeScript","https:\u002F\u002Fgrafikart.fr\u002Fformations\u002Ftypescript","cours",{"nom":1105,"url":1106,"type":1107,"anglais":124},"Les génériques (en anglais)","https:\u002F\u002Fwww.typescriptlang.org\u002Fdocs\u002Fhandbook\u002F2\u002Fgenerics.html","doc",{"nom":1109,"url":1110,"type":1107,"anglais":124},"Les types utilitaires (en anglais)","https:\u002F\u002Fwww.typescriptlang.org\u002Fdocs\u002Fhandbook\u002Futility-types.html",{"title":5,"description":1090},[1113,1115],{"nom":1114,"url":1106},"Les génériques, documentation de TypeScript (en anglais)",{"nom":1116,"url":1110},"Les types utilitaires, documentation de TypeScript (en anglais)","ts\u002F05.generiques-et-utilitaires","FZNMtEfV92dwu0UgCdNWcuX04qRcMsCoZO_JNHsYOUo",[1120,1124,1128,1132,1135,1136,1140],{"path":1121,"title":1122,"stem":1123},"\u002Fts\u002Fpourquoi-typescript","Pourquoi TypeScript","ts\u002F01.pourquoi-typescript",{"path":1125,"title":1126,"stem":1127},"\u002Fts\u002Ftypes-de-base","Types de base et fonctions","ts\u002F02.types-de-base",{"path":1129,"title":1130,"stem":1131},"\u002Fts\u002Fobjets-interfaces-types","Objets, interface et type","ts\u002F03.objets-interfaces-types",{"path":1098,"title":1133,"stem":1134},"Unions, littéraux et narrowing","ts\u002F04.unions-et-narrowing",{"path":1096,"title":5,"stem":1117},{"path":1137,"title":1138,"stem":1139},"\u002Fts\u002Ftypescript-dans-vue-et-nuxt","TypeScript dans Vue et Nuxt","ts\u002F06.typescript-dans-vue-et-nuxt",{"path":1141,"title":1142,"stem":1143},"\u002Fts","TypeScript","ts\u002Findex",[1145,1147],{"title":1133,"path":1098,"stem":1134,"description":1146,"children":-1},"Combine plusieurs types avec une union, restreins-les à des valeurs précises, puis affine le type avec typeof, in et les unions discriminées.",{"title":1138,"path":1137,"stem":1139,"description":1148,"children":-1},"Utilise TypeScript dans un composant Vue avec script setup, type les props, les événements et les ref, et vérifie les types d'un projet Nuxt.",[1150],{"path":1098,"title":1133,"ligne":56},[1152,1154,1155,1156,1157,1158,1160],{"path":1121,"title":1122,"niveau":1153,"stem":1123},"debutant",{"path":1125,"title":1126,"niveau":1153,"stem":1127},{"path":1129,"title":1130,"niveau":1153,"stem":1131},{"path":1098,"title":1133,"niveau":1095,"stem":1134},{"path":1096,"title":5,"niveau":1095,"stem":1117},{"path":1137,"title":1138,"niveau":1159,"stem":1139},"avance",{"path":1141,"title":1142,"niveau":1161,"stem":1143},"memo",1794583435549]