diff --git a/attribution.json b/attribution.json index a284ded9..8bf6bd99 100644 --- a/attribution.json +++ b/attribution.json @@ -1 +1 @@ -{"docs/documentation/fr/Nightly Builds.md":{"top":[{"name":"manusquall","gravatar":"1e8e6cdfd33a72acbc3e6750ed7afae2","count":7},{"name":"Charles Emmanuel S. Ndiaye","gravatar":"7a7a00e233291d390dd4ed213f29101c","count":3}],"total":2},"docs/documentation/id/Nightly Builds.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ja/Nightly Builds.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ko/Nightly Builds.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/pl/Nightly Builds.md":{"top":[{"name":"Tomasz Flis","gravatar":"08e7aff8ab9ee444e39a3fea0213bd27","count":6}],"total":1},"docs/documentation/pt/Nightly Builds.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/zh/Nightly Builds.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/fr/tutorials/Angular.md":{"top":[{"name":"manusquall","gravatar":"1e8e6cdfd33a72acbc3e6750ed7afae2","count":7},{"name":"Charles Emmanuel S. Ndiaye","gravatar":"7a7a00e233291d390dd4ed213f29101c","count":1}],"total":2},"docs/documentation/fr/tutorials/React.md":{"top":[{"name":"manusquall","gravatar":"1e8e6cdfd33a72acbc3e6750ed7afae2","count":7},{"name":"Charles Emmanuel S. Ndiaye","gravatar":"7a7a00e233291d390dd4ed213f29101c","count":1}],"total":2},"docs/documentation/id/javascript/Creating DTS files From JS.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/javascript/Intro to JS with TS.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/javascript/JSDoc Reference.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":7},{"name":"Orta Therox","gravatar":"28e997da43c10d99aa99273b48efe8cf","count":1}],"total":2},"docs/documentation/id/project-config/Configuring Watch.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/reference/Decorators.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/reference/Iterators and Generators.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/reference/JSX.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6},{"name":"Kemal Elmizan","gravatar":"8857fe173475cf3d2ceb45e4042ce075","count":1}],"total":2},"docs/documentation/id/reference/Mixins.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/reference/Symbols.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/tutorials/Babel with TypeScript.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/tutorials/DOM Manipulation.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/tutorials/React.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/tutorials/TypeScript Tooling in 5 minutes.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ja/javascript/Creating DTS files From JS.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ja/javascript/Intro to JS with TS.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ja/javascript/JSDoc Reference.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ja/javascript/Type Checking JavaScript Files.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ko/declaration-files/By Example.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Consumption.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Deep Dive.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Do's and Don'ts.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Introduction.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Library Structures.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Publishing.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Templates.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/get-started/TS for Functional Programmers.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"DongHwan Kim","gravatar":"860f2b0f77e66efd4822c1715f6cf1c6","count":1}],"total":2},"docs/documentation/ko/get-started/TS for JS Programmers.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/get-started/TS for OOPers.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/get-started/TS for the New Programmer.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/handbook-v2/Basics.md":{"top":[{"name":"cadenzah","gravatar":"9573931bcd6f3ddaabaa6625c661a9e6","count":12}],"total":1},"docs/documentation/ko/handbook-v2/Everyday Types.md":{"top":[{"name":"cadenzah","gravatar":"9573931bcd6f3ddaabaa6625c661a9e6","count":15}],"total":1},"docs/documentation/ko/handbook-v2/The Handbook.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/javascript/Creating DTS files From JS.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/javascript/Intro to JS with TS.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/javascript/JSDoc Reference.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/javascript/Type Checking JavaScript Files.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/project-config/Compiler Options in MSBuild.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/project-config/Compiler Options.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/project-config/Configuring Watch.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/project-config/Integrating with Build Tools.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/project-config/Project References.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"evan-moon","gravatar":"481cbcf3f8bf3d0262b108e226b33aa0","count":1}],"total":2},"docs/documentation/ko/project-config/tsconfig.json.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/reference/Declaration Merging.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ko/reference/Decorators.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/reference/Enums.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/reference/Iterators and Generators.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ko/reference/JSX.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ko/reference/Module Resolution.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"정현문","gravatar":"d88c1b4734a3c17ba0d4286e9b8bc489","count":1}],"total":2},"docs/documentation/ko/reference/Modules.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/reference/Namespaces and Modules.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"jylee","gravatar":"7f2bf1bc0e34878127edc11d01b7abfb","count":1}],"total":2},"docs/documentation/ko/reference/Namespaces.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/reference/Symbols.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ko/reference/Triple-Slash Directives.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ko/reference/Type Compatibility.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/reference/Type Inference.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ko/reference/Utility Types.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6},{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":1}],"total":2},"docs/documentation/ko/reference/Variable Declarations.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/release-notes/TypeScript 3.8.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/release-notes/TypeScript 3.9.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/release-notes/TypeScript 4.0.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/tutorials/ASP.NET Core.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/tutorials/Babel with TypeScript.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":8}],"total":1},"docs/documentation/ko/tutorials/DOM Manipulation.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/tutorials/Gulp.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/tutorials/Migrating from JavaScript.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/tutorials/React.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":9}],"total":1},"docs/documentation/ko/tutorials/TypeScript Tooling in 5 minutes.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":8}],"total":1},"docs/documentation/pl/handbook-v2/The Handbook.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6},{"name":"Jakub Cabak","gravatar":"853694852f976eb9a8d79fd335f72a6c","count":1},{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":1}],"total":3},"docs/documentation/pt/declaration-files/By Example.md":{"top":[{"name":"Perkles","gravatar":"8e49171173319c761baee81a660405b9","count":6}],"total":1},"docs/documentation/pt/declaration-files/Consumption.md":{"top":[{"name":"Leandro Lima","gravatar":"b99add103a3fe226a6e457fa18db7ab2","count":11},{"name":"Leandro","gravatar":"b99add103a3fe226a6e457fa18db7ab2","count":2}],"total":2},"docs/documentation/pt/declaration-files/Deep Dive.md":{"top":[{"name":"gustavofabro","gravatar":"9ffd9d3f734deef27039239d145249c4","count":7}],"total":1},"docs/documentation/pt/declaration-files/Do's and Don'ts.md":{"top":[{"name":"Perkles","gravatar":"8e49171173319c761baee81a660405b9","count":6}],"total":1},"docs/documentation/pt/declaration-files/Introduction.md":{"top":[{"name":"gustavofabro","gravatar":"9ffd9d3f734deef27039239d145249c4","count":6}],"total":1},"docs/documentation/pt/javascript/Creating DTS files From JS.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/javascript/Intro to JS with TS.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/javascript/JSDoc Reference.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/javascript/Type Checking JavaScript Files.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/project-config/Configuring Watch.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/project-config/Project References.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/project-config/tsconfig.json.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Declaration Merging.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Decorators.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Iterators and Generators.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/JSX.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Mixins.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":9}],"total":1},"docs/documentation/pt/reference/Module Resolution.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Modules.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Namespaces and Modules.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Namespaces.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Symbols.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Triple-Slash Directives.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Type Compatibility.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Type Inference.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Utility Types.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Variable Declarations.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/tutorials/Babel with TypeScript.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/tutorials/DOM Manipulation.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/tutorials/React.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/tutorials/TypeScript Tooling in 5 minutes.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/vo/handbook-v1/Basic Types.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/zh/project-config/tsconfig.json.md":{"top":[{"name":"Leon","gravatar":"3a0dff3d171777a5b2b8ceddf691ba35","count":8}],"total":1},"docs/documentation/ko/declaration-files/templates/module-class.d.ts.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/templates/module-function.d.ts.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/handbook-v2/Type Manipulation/Generics.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1}} \ No newline at end of file +{"docs/documentation/fr/Nightly Builds.md":{"top":[{"name":"manusquall","gravatar":"1e8e6cdfd33a72acbc3e6750ed7afae2","count":7},{"name":"Charles Emmanuel S. Ndiaye","gravatar":"7a7a00e233291d390dd4ed213f29101c","count":3}],"total":2},"docs/documentation/id/Nightly Builds.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ja/Nightly Builds.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ko/Nightly Builds.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/pl/Nightly Builds.md":{"top":[{"name":"Tomasz Flis","gravatar":"08e7aff8ab9ee444e39a3fea0213bd27","count":6}],"total":1},"docs/documentation/pt/Nightly Builds.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/zh/Nightly Builds.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/fr/get-started/TS for JS Programmers.md":{"top":[{"name":"mk360","gravatar":"068fd63f20d8f098811430a7465c73db","count":7}],"total":1},"docs/documentation/fr/get-started/TS for OOPers.md":{"top":[{"name":"mk360","gravatar":"068fd63f20d8f098811430a7465c73db","count":8}],"total":1},"docs/documentation/fr/get-started/TS for the New Programmer.md":{"top":[{"name":"mk360","gravatar":"068fd63f20d8f098811430a7465c73db","count":8}],"total":1},"docs/documentation/fr/tutorials/Angular.md":{"top":[{"name":"manusquall","gravatar":"1e8e6cdfd33a72acbc3e6750ed7afae2","count":7},{"name":"Charles Emmanuel S. Ndiaye","gravatar":"7a7a00e233291d390dd4ed213f29101c","count":1}],"total":2},"docs/documentation/fr/tutorials/React.md":{"top":[{"name":"manusquall","gravatar":"1e8e6cdfd33a72acbc3e6750ed7afae2","count":7},{"name":"Charles Emmanuel S. Ndiaye","gravatar":"7a7a00e233291d390dd4ed213f29101c","count":1}],"total":2},"docs/documentation/id/javascript/Creating DTS files From JS.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/javascript/Intro to JS with TS.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/javascript/JSDoc Reference.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":7},{"name":"Orta Therox","gravatar":"28e997da43c10d99aa99273b48efe8cf","count":1}],"total":2},"docs/documentation/id/project-config/Configuring Watch.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/reference/Decorators.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/reference/Iterators and Generators.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/reference/JSX.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6},{"name":"Kemal Elmizan","gravatar":"8857fe173475cf3d2ceb45e4042ce075","count":1}],"total":2},"docs/documentation/id/reference/Mixins.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/reference/Symbols.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/tutorials/Babel with TypeScript.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/tutorials/DOM Manipulation.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/tutorials/React.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/id/tutorials/TypeScript Tooling in 5 minutes.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ja/javascript/Creating DTS files From JS.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ja/javascript/Intro to JS with TS.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ja/javascript/JSDoc Reference.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ja/javascript/Type Checking JavaScript Files.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ko/declaration-files/By Example.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":2},"docs/documentation/ko/declaration-files/Consumption.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Deep Dive.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Do's and Don'ts.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Introduction.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Library Structures.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Publishing.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/Templates.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/get-started/TS for Functional Programmers.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1},{"name":"kimjngyun","gravatar":"c598fd07d8fd4e0f513ab52801535c68","count":1},{"name":"DongHwan Kim","gravatar":"860f2b0f77e66efd4822c1715f6cf1c6","count":1}],"total":4},"docs/documentation/ko/get-started/TS for JS Programmers.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1},{"name":"nowjin","gravatar":"3752ed4cf1b60f215987dccef41f094c","count":1}],"total":3},"docs/documentation/ko/get-started/TS for OOPers.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":2},"docs/documentation/ko/get-started/TS for the New Programmer.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":2},"docs/documentation/ko/handbook-v2/Basics.md":{"top":[{"name":"cadenzah","gravatar":"9573931bcd6f3ddaabaa6625c661a9e6","count":12},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1},{"name":"Conan Kunhwan Ahn","gravatar":"e74dc6827b15de2b8030af2bc644cd19","count":1},{"name":"Gaon Kim","gravatar":"34d2a83d7bf890a7cfdda22a978522d9","count":1}],"total":4},"docs/documentation/ko/handbook-v2/Everyday Types.md":{"top":[{"name":"cadenzah","gravatar":"9573931bcd6f3ddaabaa6625c661a9e6","count":15},{"name":"GengJun","gravatar":"f2ccf4d7411bed8c1e0afe44e7efa676","count":1},{"name":"owen","gravatar":"f2ccf4d7411bed8c1e0afe44e7efa676","count":1},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1},{"name":"Conan Kunhwan Ahn","gravatar":"e74dc6827b15de2b8030af2bc644cd19","count":1}],"total":5},"docs/documentation/ko/handbook-v2/The Handbook.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/handbook-v2/Understanding Errors.md":{"top":[{"name":"hyunjin lee","gravatar":"0843efae3ede8e876ee04ca214a933f9","count":15},{"name":"hyunjin","gravatar":"6328e07e805b59df2a84d35f12de6d91","count":10},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":3},"docs/documentation/ko/javascript/Creating DTS files From JS.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Sungchang Park","gravatar":"221d01fcd440a697eafdc91181b143a7","count":1}],"total":2},"docs/documentation/ko/javascript/Intro to JS with TS.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/javascript/JSDoc Reference.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/javascript/Type Checking JavaScript Files.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/project-config/Compiler Options in MSBuild.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/project-config/Compiler Options.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/project-config/Configuring Watch.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":2},"docs/documentation/ko/project-config/Integrating with Build Tools.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":2},"docs/documentation/ko/project-config/Project References.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"evan-moon","gravatar":"481cbcf3f8bf3d0262b108e226b33aa0","count":1}],"total":2},"docs/documentation/ko/project-config/tsconfig.json.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/reference/Declaration Merging.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":2},"docs/documentation/ko/reference/Decorators.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"hyo-choi","gravatar":"15d8c690edfbd8dd947b157feed1cd14","count":1},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":3},"docs/documentation/ko/reference/Enums.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/reference/Iterators and Generators.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":2},"docs/documentation/ko/reference/JSX.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":2},"docs/documentation/ko/reference/Module Resolution.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"hyo-choi","gravatar":"15d8c690edfbd8dd947b157feed1cd14","count":1},{"name":"정현문","gravatar":"d88c1b4734a3c17ba0d4286e9b8bc489","count":1}],"total":3},"docs/documentation/ko/reference/Modules.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/reference/Namespaces and Modules.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1},{"name":"jylee","gravatar":"7f2bf1bc0e34878127edc11d01b7abfb","count":1}],"total":3},"docs/documentation/ko/reference/Namespaces.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"hyo-choi","gravatar":"15d8c690edfbd8dd947b157feed1cd14","count":1}],"total":2},"docs/documentation/ko/reference/Symbols.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ko/reference/Triple-Slash Directives.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":2},"docs/documentation/ko/reference/Type Compatibility.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/reference/Type Inference.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/ko/reference/Utility Types.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6},{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":1}],"total":2},"docs/documentation/ko/reference/Variable Declarations.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/release-notes/TypeScript 3.8.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Jonghakseo","gravatar":"a0a6868ec721de5afbd0adef4055e928","count":1}],"total":2},"docs/documentation/ko/release-notes/TypeScript 3.9.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Jonghakseo","gravatar":"a0a6868ec721de5afbd0adef4055e928","count":1}],"total":2},"docs/documentation/ko/release-notes/TypeScript 4.0.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":2},"docs/documentation/ko/tutorials/ASP.NET Core.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/tutorials/Babel with TypeScript.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":8},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1},{"name":"warmwhiten","gravatar":"00d0e16ced27b90633a8962ed5c31649","count":1}],"total":3},"docs/documentation/ko/tutorials/DOM Manipulation.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":2},"docs/documentation/ko/tutorials/Gulp.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/tutorials/Migrating from JavaScript.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/tutorials/React.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":9}],"total":1},"docs/documentation/ko/tutorials/TypeScript Tooling in 5 minutes.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":8}],"total":1},"docs/documentation/pl/handbook-v2/The Handbook.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6},{"name":"Jakub Cabak","gravatar":"853694852f976eb9a8d79fd335f72a6c","count":1},{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":1}],"total":3},"docs/documentation/pt/declaration-files/By Example.md":{"top":[{"name":"Perkles","gravatar":"8e49171173319c761baee81a660405b9","count":6}],"total":1},"docs/documentation/pt/declaration-files/Consumption.md":{"top":[{"name":"Leandro Lima","gravatar":"b99add103a3fe226a6e457fa18db7ab2","count":11},{"name":"Leandro","gravatar":"b99add103a3fe226a6e457fa18db7ab2","count":2}],"total":2},"docs/documentation/pt/declaration-files/Deep Dive.md":{"top":[{"name":"gustavofabro","gravatar":"9ffd9d3f734deef27039239d145249c4","count":7}],"total":1},"docs/documentation/pt/declaration-files/Do's and Don'ts.md":{"top":[{"name":"Perkles","gravatar":"8e49171173319c761baee81a660405b9","count":6}],"total":1},"docs/documentation/pt/declaration-files/Introduction.md":{"top":[{"name":"gustavofabro","gravatar":"9ffd9d3f734deef27039239d145249c4","count":6}],"total":1},"docs/documentation/pt/get-started/TS for Functional Programmers.md":{"top":[{"name":"luk3skyw4lker","gravatar":"41c471de17c0920eb36de6c653234713","count":6}],"total":1},"docs/documentation/pt/get-started/TS for JS Programmers.md":{"top":[{"name":"luk3skyw4lker","gravatar":"41c471de17c0920eb36de6c653234713","count":6}],"total":1},"docs/documentation/pt/get-started/TS for OOPers.md":{"top":[{"name":"luk3skyw4lker","gravatar":"41c471de17c0920eb36de6c653234713","count":8}],"total":1},"docs/documentation/pt/get-started/TS for the New Programmer.md":{"top":[{"name":"luk3skyw4lker","gravatar":"41c471de17c0920eb36de6c653234713","count":6},{"name":"arimariojesus","gravatar":"6ada5060638adefdffb9a44bcbf16de3","count":1}],"total":2},"docs/documentation/pt/javascript/Creating DTS files From JS.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/javascript/Intro to JS with TS.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/javascript/JSDoc Reference.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/javascript/Type Checking JavaScript Files.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/project-config/Configuring Watch.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/project-config/Project References.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/project-config/tsconfig.json.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Declaration Merging.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Decorators.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Iterators and Generators.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/JSX.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Mixins.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":9}],"total":1},"docs/documentation/pt/reference/Module Resolution.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Modules.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Namespaces and Modules.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Namespaces.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Symbols.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Triple-Slash Directives.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Type Compatibility.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Type Inference.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Utility Types.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/reference/Variable Declarations.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/tutorials/Babel with TypeScript.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/tutorials/DOM Manipulation.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/tutorials/React.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/pt/tutorials/TypeScript Tooling in 5 minutes.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/vo/handbook-v1/Basic Types.md":{"top":[{"name":"Orta","gravatar":"bcfa5d8f5699be0134ffb16424b42610","count":6}],"total":1},"docs/documentation/zh/get-started/TS for JS Programmers.md":{"top":[{"name":"Xavi Lee","gravatar":"43234add53f35134fc6fd80849a721e5","count":6}],"total":1},"docs/documentation/zh/get-started/TS for the New Programmer.md":{"top":[{"name":"Szin","gravatar":"127f072e163882ba4100e6e3ea3c0038","count":8},{"name":"Xavi Lee","gravatar":"43234add53f35134fc6fd80849a721e5","count":1}],"total":2},"docs/documentation/zh/handbook-v2/Basics.md":{"top":[{"name":"Chorer","gravatar":"4e967892285c6eb495e2c0e9d969ecc8","count":6}],"total":1},"docs/documentation/zh/handbook-v2/Everyday Types.md":{"top":[{"name":"htmlin","gravatar":"8c831a8aef84b9679b5d9f9cdfa6b27a","count":9}],"total":1},"docs/documentation/zh/project-config/tsconfig.json.md":{"top":[{"name":"Leon","gravatar":"3a0dff3d171777a5b2b8ceddf691ba35","count":8}],"total":1},"docs/documentation/ko/declaration-files/templates/module-class.d.ts.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/declaration-files/templates/module-function.d.ts.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/handbook-v2/Type Manipulation/Conditional Types.md":{"top":[{"name":"bumkeyy","gravatar":"8b6991ac4cca5b115aa19b62f05d1373","count":8},{"name":"Kibeom Kwon","gravatar":"8b6991ac4cca5b115aa19b62f05d1373","count":3},{"name":"Joy C","gravatar":"9c9f9ac925ce05b004ca7590dd7c1ea1","count":1}],"total":3},"docs/documentation/ko/handbook-v2/Type Manipulation/Generics.md":{"top":[{"name":"Jihoon Seo","gravatar":"ecf0fadc78946edd957a076fc88e9bb6","count":6}],"total":1},"docs/documentation/ko/handbook-v2/Type Manipulation/Indexed Access Types.md":{"top":[{"name":"bumkeyy","gravatar":"8b6991ac4cca5b115aa19b62f05d1373","count":7}],"total":1},"docs/documentation/ko/handbook-v2/Type Manipulation/Keyof Type Operator.md":{"top":[{"name":"bumkeyy","gravatar":"8b6991ac4cca5b115aa19b62f05d1373","count":7}],"total":1},"docs/documentation/ko/handbook-v2/Type Manipulation/Mapped Types.md":{"top":[{"name":"bumkeyy","gravatar":"8b6991ac4cca5b115aa19b62f05d1373","count":7}],"total":1},"docs/documentation/ko/handbook-v2/Type Manipulation/Typeof Type Operator.md":{"top":[{"name":"bumkeyy","gravatar":"8b6991ac4cca5b115aa19b62f05d1373","count":7}],"total":1},"docs/documentation/pt/declaration-files/templates/global-modifying-module.d.ts.md":{"top":[{"name":"gustavofabro","gravatar":"9ffd9d3f734deef27039239d145249c4","count":6}],"total":1},"docs/documentation/zh/handbook-v2/Type Manipulation/Conditional Types.md":{"top":[{"name":"htmlin","gravatar":"8c831a8aef84b9679b5d9f9cdfa6b27a","count":7}],"total":1}} \ No newline at end of file diff --git a/docs/documentation/fr/get-started/TS for JS Programmers.md b/docs/documentation/fr/get-started/TS for JS Programmers.md new file mode 100644 index 00000000..f349f88b --- /dev/null +++ b/docs/documentation/fr/get-started/TS for JS Programmers.md @@ -0,0 +1,291 @@ +--- +title: TypeScript pour les développeurs JavaScript +short: TypeScript pour les développeurs JS +layout: docs +permalink: /fr/docs/handbook/typescript-in-5-minutes.html +oneline: Apprenez comment TypeScript étend JavaScript +--- + +TypeScript a une relation inhabituelle avec JavaScript. TypeScript offre toutes les fonctionnalités de JavaScript, avec une couche supplémentaire de fonctionnalités : le système de typage. + +JavaScript fournit des primitives, comme `string` et `number`, mais aucune vérification n'est faite pour s'assurer que les assignations que vous faites sont correctes. TypeScript le fait. + +Cela signifie que votre code JavaScript existant est également du code TypeScript. L'avantage principal de TypeScript est sa capacité à exposer les comportements imprévus dans votre code, diminuant les risques de bugs. + +Ce tutoriel fournira une vue d'ensemble de TypeScript, et va se concentrer sur son système de typage. + +## Types par Inférence + +TypeScript connaît le JavaScript et générera les types pour vous la plupart du temps. +Par exemple, en créant une variable et en lui assignant une certaine valeur, TypeScript va utiliser cette valeur en tant que type. + +```ts twoslash +let helloWorld = "Hello World"; +// ^? +``` + +En comprenant comment JavaScript fonctionne, TypeScript peut créer un système qui accepte du code JavaScript, avec des types. Le résultat est un système de types qui n'a pas besoin de déclarations explicites de types dans votre code. C'est comme ça que TypeScript sait que `helloWorld` est un `string` dans l'exemple précédent (TypeScript a _inféré_ le type `string` de `helloWorld`). + +Il se peut que vous ayez écrit du JavaScript dans Visual Studio Code, et ayez obtenu de l'autocomplétion de la part de l'éditeur. Visual Studio Code utilise TypeScript en arrière-plan pour faciliter le travail avec JavaScript. + +## Définir des Types + +Vous pouvez utiliser une variété de design patterns en JavaScript. Cependant, certains patterns rendent difficile l'inférence automatique de types (par exemple, les patterns qui utilisent la programmation dynamique). Pour couvrir ces cas d'usage, TypeScript supporte une extension de JavaScript qui vous offre la possibilité de définir vos types. + +Par exemple, il est possible de créer un objet qui contient un `name: string` et un `id: number` en écrivant: + +```ts twoslash +const user = { + name: "Hayes", + id: 0, +}; +``` + +Vous pouvez explicitement décrire la forme de cet objet en utilisant une déclaration d'`interface`: + +```ts twoslash +interface User { + name: string; + id: number; +} +``` + +Vous pourrez déclarer que votre objet JavaScript respecte cette nouvelle `interface` en utilisant une syntaxe comme `: TypeName` après une déclaration de variable : + +```ts twoslash +interface User { + name: string; + id: number; +} +// ---cut--- +const user: User = { + name: "Hayes", + id: 0, +}; +``` + +TypeScript va vous prévenir si vous fournissez un objet qui ne correspond pas à votre interface : + +```ts twoslash +// @errors: 2322 +interface User { + name: string; + id: number; +} + +const user: User = { + username: "Hayes", + id: 0, +}; +``` + +JavaScript (par conséquent, TypeScript) supporte les classes et la programmation orientée objet. Vous pouvez utiliser une déclaration d'interface avec une classe : + +```ts twoslash +interface User { + name: string; + id: number; +} + +class UserAccount { + name: string; + id: number; + + constructor(name: string, id: number) { + this.name = name; + this.id = id; + } +} + +const user: User = new UserAccount("Murphy", 1); +``` + +Vous pouvez utiliser les interfaces pour annoter les types de paramètres et valeurs de retour de fonctions : + +```ts twoslash +// @noErrors +interface User { + name: string; + id: number; +} +// ---cut--- +function getAdminUser(): User { + //... +} + +function deleteUser(user: User) { + // ... +} +``` + +JavaScript fournit déjà un petit ensemble de types primitifs, dont vous pouvez vous servir dans une interface : `boolean`, `bigint`, `null`, `number`, `string`, `symbol`, et `undefined`. TypeScript étend cette liste en y ajoutant `any` (tout permettre), [`unknown`](/play#example/unknown-and-never) (s'assurer que quiconque se sert de ce type déclare le type voulu), [`never`](/play#example/unknown-and-never) (il est impossible d'avoir ce type), et `void` (une fonction qui retourne `undefined` ou ne retourne rien). + +Vous verrez deux syntaxes pour créer des types : [les Interfaces et les Types](/play/?e=83#example/types-vs-interfaces). Préférez une `interface`, mais utilisez un `type` si vous avez besoin d'une fonctionnalité particulière. + +## Composition de Types + +Avec TypeScript, il est possible de combiner plusieurs types simples en un type complexe. Deux manières populaires existent : les unions, et les types génériques. + +### Unions + +Une union vous permet de déclarer qu'un type pourrait en être un parmi certains. Par exemple, une façon de décrire le type `boolean` serait de dire qu'il est soit `true`, soit `false`: + +```ts twoslash +type MyBool = true | false; +``` + +_Note:_ Si vous survolez `MyBool`, vous verrez que le type est classé en tant que `boolean`. C'est une caractéristique du Système Structurel de Types (plus de détails ci-dessous). + +Un usage populaire des types union est de décrire les ensembles de `string` ou `number` acceptables en tant que valeurs : + +```ts twoslash +type WindowStates = "open" | "closed" | "minimized"; +type LockStates = "locked" | "unlocked"; +type PositiveOddNumbersUnderTen = 1 | 3 | 5 | 7 | 9; +``` + +Les unions fournissent également une manière de gérer les types hétérogènes. Par exemple, vous pouvez avoir une fonction qui accepte un `array` ou un `string` : + +```ts twoslash +function getLength(obj: string | string[]) { + return obj.length; +} +``` + +Pour connaître le type d'une variable, utilisez `typeof` : + +| Type | Condition | +| --------- | ---------------------------------- | +| string | `typeof s === "string"` | +| number | `typeof n === "number"` | +| boolean | `typeof b === "boolean"` | +| undefined | `typeof undefined === "undefined"` | +| function | `typeof f === "function"` | +| array | `Array.isArray(a)` | + +Vous pouvez faire en sorte qu'une fonction retourne des valeurs différentes en fonction du type de l'argument passé : + + +```ts twoslash +function wrapInArray(obj: string | string[]) { + if (typeof obj === "string") { + return [obj]; +// ^? + } + return obj; +} +``` + +### Types Génériques + +Les types génériques fournissent des variables aux types. Les tableaux (arrays) seraient un exemple commun. Un tableau sans type générique pourrait tout contenir, alors qu'un tableau avec un type générique restreint son contenu à ce type générique. + +```ts +type StringArray = Array; +type NumberArray = Array; +type ObjectWithNameArray = Array<{ name: string }>; +``` + +Vous pouvez utiliser les types génériques avec vos propres types : + +```ts twoslash +// @errors: 2345 +interface Backpack { + add: (obj: Type) => void; + get: () => Type; +} + +// Cette ligne est un raccourci pour informer TS de l'existence d'une +// d'une constante appelée `backpack`, sans s'inquiéter d'où elle viendrait. +declare const backpack: Backpack; + +// object est un string, vu que nous avons déclaré un string +// en tant que variable à `backpack`. +const object = backpack.get(); + +// Vu que backpack est un string, vous ne pouvez pas donner de nombre +// à la fonction add. +backpack.add(23); +``` + +## Système Structurel de Types + +L'un des principes au cœur de TypeScript est que la vérification des types se concentre sur la _forme_ de la valeur. Ce principe est parfois appelé "typage structurel". + +Dans un système structurel, si deux objets ont la même forme (la même structure, d'où le nom), ils sont considérés comme étant du même type. + +```ts twoslash +interface Point { + x: number; + y: number; +} + +function logPoint(p: Point) { + console.log(`${p.x}, ${p.y}`); +} + +// affiche "12, 26" +const point = { x: 12, y: 26 }; +logPoint(point); +``` + +La variable `point` n'a jamais été déclarée en tant que `Point`. Mais TypeScript compare la forme de `point` la variable à la forme de `Point` l'interface. Les deux ont la même forme, donc l'appel est validé. + +La correspondance entre formes requiert uniquement la correspondance d'un sous-ensemble des propriétés d'un objet. + +```ts twoslash +// @errors: 2345 +interface Point { + x: number; + y: number; +} + +function logPoint(p: Point) { + console.log(`${p.x}, ${p.y}`); +} +// ---cut--- +const point3 = { x: 12, y: 26, z: 89 }; +logPoint(point3); // affiche "12, 26" + +const rect = { x: 33, y: 3, width: 30, height: 80 }; +logPoint(rect); // affiche "33, 3" + +const color = { hex: "#187ABF" }; +logPoint(color); +``` + +Il n'y a aucune différence entre la façon dont les classes et les objets se conforment aux formes : + +```ts twoslash +// @errors: 2345 +interface Point { + x: number; + y: number; +} + +function logPoint(p: Point) { + console.log(`${p.x}, ${p.y}`); +} +// ---cut--- +class VirtualPoint { + x: number; + y: number; + + constructor(x: number, y: number) { + this.x = x; + this.y = y; + } +} + +const newVPoint = new VirtualPoint(13, 56); +logPoint(newVPoint); // affiche "13, 56" +``` + +Si un objet ou une classe possède toutes les propriétés requises, TypeScript dira que la variable correspond, peu importe les détails d'implémentation. + +## Prochaines étapes + +C'était un bref résumé de la syntaxe et des outils régulièrement utilisés en TypeScript. À partir de là, vous pourrez : + +- Lire le Manuel [du début à la fin](/docs/handbook/intro.html) (30m) +- Explorer les [exemples du bac à sable](/play#show-examples) diff --git a/docs/documentation/fr/get-started/TS for OOPers.md b/docs/documentation/fr/get-started/TS for OOPers.md new file mode 100644 index 00000000..2a797bf1 --- /dev/null +++ b/docs/documentation/fr/get-started/TS for OOPers.md @@ -0,0 +1,194 @@ +--- +title: TypeScript pour les Développeurs Java/C# +short: TS pour les Développeurs Java/C# +layout: docs +permalink: /fr/docs/handbook/typescript-in-5-minutes-oop.html +oneline: Apprenez TypeScript si vous avez de l'expérience avec les langages orientés objet +--- + +TypeScript est un choix populaire pour les développeurs habitués aux autres langages à typage statique, comme le C# et le Java. + +Le système de types de TypeScript offre la plupart de ces bénéfices : meilleure complétion de code, détection d'erreurs plus précoce, communication plus claire entre les composantes de votre programme. +TypeScript fournit plusieurs fonctionnalités familières à ces développeurs, mais il est intéressant de faire un pas en arrière et apprendre comment le JavaScript (et par conséquent, TypeScript) diffère des langages orientés objet traditionnels. +Comprendre ces différences vous permettra d'écrire du code JavaScript de meilleure qualité, et d'éviter les pièges communs dans lesquels les développeurs passant de C#/Java à TypeScript peuvent tomber. + +## Apprendre le JavaScript + +Si vous êtes déjà familier avec le JavaScript, mais vous êtes principalement un développeur Java ou C#, cette page d'introduction peut expliquer certaines idées fausses et pièges auxquels vous seriez susceptible. +Certaines façons avec lesquelles TypeScript modélise les types sont très différentes du Java ou du C#. Il est important de s'en souvenir en apprenant TypeScript. + +Si vous êtes un développeur Java ou C#, et vous êtes nouveau avec JavaScript en général, nous recommandons d'apprendre un peu de JavaScript _sans les types_ d'abord, afin de comprendre son comportement lors de l'exécution. +Vu que TypeScript ne change pas comment votre code _s'exécute_, vous devrez quand même apprendre le JavaScript pour écrire du code qui fait réellement quelque chose ! + +Il est important de se rappeler que TypeScript utilise le même _runtime_ que le JavaScript, donc toute ressource sur comment accomplir un comportement particulier (conversion d'un string à un nombre, affichage d'une alerte, écriture d'un fichier, etc.) s'appliquera également en TypeScript. +Ne vous limitez pas à ce qui est spécifique à TypeScript ! + +## Repenser les classes + +Le C# et le Java sont ce qu'on pourrait appeler des langages à _POO obligatoire_. +Dans ces langages, la _classe_ est l'unité basique d'organisation de code, ainsi que le conteneur de base de toutes les données _et_ de la logique à l'exécution. +Obliger toute la fonctionnalité et toutes les données à être contenues dans des classes peut être un bon modèle de domaine pour certains problèmes, mais tous les modèles _ne doivent pas_ être représentés de cette façon. + +### Fonctions et données libres + +En JavaScript, les fonctions peuvent être placées n'importe où, et les données peuvent être librement relayées sans être cantonnées à une `class` ou une `struct`. +Cette flexibilité est extrêmement puissante. +Ces fonctions "libres" (celles qui ne sont pas associées à une classe), qui travaillent sur des données sans hiérarchie orientée objet, ont tendance à être le modèle préféré pour écrire un programme en JavaScript. + +### Classes statiques + +De plus, certaines structures du C# et du Java, comme les singletons et les classes statiques, ne sont pas nécessaires en TypeScript. + +## POO en TypeScript + +Cela dit, vous pouvez quand même utiliser des classes si vous le souhaitez ! +Certains problèmes ont une solution qui correspond à l'approche POO classique, et la capacité de TypeScript à supporter les classes JavaScript rendra ces solutions encore plus puissantes. +TypeScript supporte plusieurs patterns comme l'implémentation d'interfaces, l'héritage, et les méthodes statiques. + +Nous couvrirons les classes plus tard dans ce guide. + +## Repenser les types + +La façon dont TypeScript comprend la notion de _type_ est très différente du C# et du Java. +Explorons certaines différences. + +### Systèmes de Types Nominaux Réifiés + +En C# ou Java, toute valeur a exactement un type - `null`, une primitive, ou un type de classe. +Nous pouvons appeler des méthodes comme `value.GetType()` ou `value.getClass()` pour obtenir le type exact à l'exécution. +La définition de ce type réside dans une certaine classe sous un certain nom, et nous n'avons pas le droit d'utiliser deux classes à formes similaires de façon interchangeable, sauf si une relation explicite d'héritage existe ou une interface en commun est implémentée. + +Ces aspects décrivent un système _réifié et nominal_ de types. +Les types qu'on écrit sont présents à l'exécution, et ils sont liés à eux via leurs déclarations, pas leurs structures. + +### Types en tant qu'ensembles + +En C# ou Java, cela a du sens de faire une correspondance entre un type à l'exécution et sa déclarations à la compilation. + +En TypeScript, il vaut mieux de penser aux types comme des _ensembles de valeurs_ qui partagent quelque chose en commun. +Parce que les types ne sont que des ensembles, une valeur peut appartenir à _plusieurs_ ensembles en même temps. + +Une fois que vous pensez aux types en tant qu'ensembles, certaines opérations deviennent naturelles. +Par exemple, en C#, il est bizarre de transmettre une valeur qui est _soit_ un `string` ou `int`, parce qu'il n'existe aucun type les représentant tous les deux. + +En TypeScript, ce procédé devient naturel quand vous pensez aux types en tant qu'ensembles. +Comment décrire une valeur qui appartient, soit à l'ensemble des `string`, soit à celui des `number` ? +Elle appartient simplement à l'_union_ de ces ensembles : `string | number`. + +TypeScript fournit un certain nombre de mécanismes pour travailler avec les types de façons similaires à la théorie des ensembles, et ces façons seront plus intuitives si on pense aux types en tant qu'ensembles. + +### Types Structurels Effacés + +En TypeScript, les objets n'ont _pas_ de seul et unique type. +Par exemple, si nous créons un objet qui correspond à une interface, nous pouvons utiliser cet objet là où l'interface est attendue même si aucune relation de déclaration n'existait entre les deux. + +```ts twoslash +interface Pointlike { + x: number; + y: number; +} +interface Named { + name: string; +} + +function logPoint(point: Pointlike) { + console.log("x = " + point.x + ", y = " + point.y); +} + +function logName(x: Named) { + console.log("Hello, " + x.name); +} + +const obj = { + x: 0, + y: 0, + name: "Origin", +}; + +logPoint(obj); +logName(obj); +``` + +Le système de types de TypeScript est _structurel_, et non nominal : nous pouvons utiliser `obj` en tant que `Pointlike` parce qu'`obj` a les propriétés `x` et `y` qui sont toutes les deux des nombres. +Les relations entre types sont déterminées par les propriétés qu'ils contiennent, et non pas avec une relation de déclaration entre eux. + +Le système de types de TypeScript n'est également _pas réifié_: rien ne va pouvoir nous dire qu'`obj` est un `Pointlike`, lors de l'exécution. +D'ailleurs, le type `Pointlike` n'est _même pas présent_ lors de l'exécution. + +Si nous revenons à notre façon de réfléchir aux types _en tant qu'ensemble_, nous pouvons dire qu'`obj` est membre de l'ensemble `Pointlike`, ainsi que de l'ensemble `Named`. + +### Conséquences du typage structurel + +Deux aspects particuliers de ce système surprennent souvent les développeurs POO. + +#### Types vides + +Le premier est que le _type vide_ a l'air d'agir de manière impromptue : + +```ts twoslash +class Empty {} + +function fn(arg: Empty) { + // fais quelque chose ? +} + +// Pas d'erreur, mais ce n'est pas un Empty ? +fn({ k: 10 }); +``` + +TypeScript détermine si l'appel à `fn` est valide en déterminant si l'argument fourni est un `Empty` valide. +Cela est accompli en examinant la _structure_ de `{ k: 10 }` et `class Empty { }`. +Nous pouvons voir que `{ k: 10 }` a _toutes_ les propriétés d'`Empty` vu qu'`Empty` n'a aucune propriété. +C'est donc un appel valide ! + +Cela peut paraître surprenant, mais c'est au final une relation très similaire à celle respectées dans les langages POO nominaux. +Une sous-classe ne peut pas _retirer_ une propriété de sa classe-mère, parce que faire cela détruirait la relation de sous-type naturelle existant entre la sous-classe et sa classe-mère. +Les systèmes de type structurels identifient cette relation en décrivant les sous-types de façon à avoir des propriétés à types compatibles. + +#### Types identiques + +Les types identiques sont une autre source fréquente de surprises : + +```ts +class Car { + drive() { + // accélérer + } +} +class Golfer { + drive() { + // frapper la balle fort + } +} + +// Pas d'erreur ? +let w: Car = new Golfer(); +``` + +Encore une fois, ceci n'est pas une erreur parce que les _structures_ de ces classes sont les mêmes. +Cela peut paraître comme une source de confusion, mais en pratique, les classes identiques n'ayant aucun rapport ne sont pas communes. + +Nous apprendrons plus sur comment les classes sont liées l'une à l'autre dans leur chapitre. + +### Réflexivité + +Les développeurs POO ont l'habitude de pouvoir demander le type de n'importe quelle valeur, même générique : + +```csharp +// C# +static void LogType() { + Console.WriteLine(typeof(T).Name); +} +``` + +Mais parce que le système de types de TypeScript est complètement effacé, aucune information sur, par exemple, l'instanciation d'un type générique n'est disponible à l'exécution. + +JavaScript possède quelques opérateurs comme `typeof` et `instanceof`, mais souvenez-vous que ces opérateurs agissent sur les valeurs, tel qu'elles existent dans le code sans informations de types. +Par exemple, `typeof (new Car())` va retourner `"object"`, et non `Car` ni `"Car"`. + +## Prochaines étapes + +C'était un bref résumé de la syntaxe et des outils régulièrement utilisés en TypeScript. À partir de là, vous pourrez : + +- Lire le Manuel [du début à la fin](/docs/handbook/intro.html) (30m) +- Explorer les [exemples du bac à sable](/play#show-examples) diff --git a/docs/documentation/fr/get-started/TS for the New Programmer.md b/docs/documentation/fr/get-started/TS for the New Programmer.md new file mode 100644 index 00000000..72892f75 --- /dev/null +++ b/docs/documentation/fr/get-started/TS for the New Programmer.md @@ -0,0 +1,192 @@ +--- +title: TypeScript pour les nouveaux programmeurs +short: TS pour les nouveaux programmeurs +layout: docs +permalink: /fr/docs/handbook/typescript-from-scratch.html +oneline: Learn TypeScript from scratch +--- + +Félicitations, vous avez choisi TypeScript comme premier langage — déjà une bonne décision ! + +Vous avez peut-être déjà entendu dire que TypeScript est une "variante" de JavaScript. +La relation entre les deux est unique parmi les langages de programmation existants, et étudier cette relation vous permettra de comprendre ce qu'ajoute TypeScript à JavaScript. + +## Bref historique de JavaScript + +JavaScript (aussi connu sous le nom ECMAScript) était à l'origine un simple langage de scripting pour navigateurs. +Quand il fut inventé, il était utilisé pour de petits extraits de code dans une page web — aller au-delà d'une douzaine de ligne était inhabituel. +De ce fait, les navigateurs exécutaient du code JS assez lentement. +Cependant, la popularité de JavaScript grandira avec le temps, et les développeurs web ont commencé à s'en servir pour créer des expériences interactives. + +Les développeurs de navigateurs Web répondirent à cette croissance de fréquence d'usage en optimisant les environnements d'exécution (compilation dynamique) et en élargissant le champ du possible avec JS (en ajoutant des APIs). Cela contribua à un usage encore plus répandu parmi les développeurs web. +Un site web moderne, de nos jours, contient des centaines de milliers de lignes de code. Ceci est en phase avec la façon dont le web a grandi, partant d'un simple ensemble de pages statiques, pour devenir une plateforme d'applications riches pour tout et sur tout. + +De plus, le JS est devenu assez populaire pour être utilisé en dehors de navigateurs, Node.js ayant marqué l'implémentation de JS dans un environnement côté serveur. +Cette capacité à s'exécuter partout a fait du langage un choix populaire pour le développement d'applications cross-platform. +Il y a beaucoup de développeurs dont le stack technique n'est constitué que de JavaScript ! + +Pour résumer, ce langage a été créé à l'origine pour répondre à des besoins simples, puis a évolué pour supporter l'exécution de millions de lignes. +Chaque langage a ses propres points bizarres et surprises, le JS ne faisant pas exception dû à ses débuts : + +- L'opérateur d'égalité (`==`) _convertit_ ses arguments, conduisant à un comportement bizarre : + + ```js + if ("" == 0) { + // C'est vrai, mais pourquoi ? + } + if (1 < x < 3) { + // C'est vrai peu importe la valeur de x ! + } + ``` + +- JavaScript permet l'accès à des propriétés inexistantes : + + ```js + const obj = { width: 10, height: 15 }; + const area = obj.width * obj.heigth; + // Bonne chance pour savoir pourquoi "area" est égale à NaN + ``` + +La plupart des langages lanceraient une erreur lors de ces situations. Certains le font à la compilation — avant l'exécution de quoi que ce soit. +Cette absence d'erreurs et ses mauvaises surprises sont gérables pour de petits programmes, mais beaucoup moins à l'échelle d'une grande application. + +## TypeScript : un vérificateur statique de types + +Nous disions que certains langages interdiraient l'exécution de code erroné. +La détection d'erreurs dans le code sans le lancer s'appelle la _vérification statique_. +La distinction entre ce qui est une erreur de ce qui ne l'est pas, en partant des valeurs avec lesquelles on travaille, s'appelle la vérification statique de types. + +TypeScript vérifie les erreurs d'un programme avant l'exécution, et fait cela en se basant sur les _types de valeurs_, c'est un _vérificateur statique_. +Par exemple, l'exemple ci-dessus avait une erreur à cause du _type_ d'`obj` : + +```ts twoslash +// @errors: 2551 +const obj = { width: 10, height: 15 }; +const area = obj.width * obj.heigth; +``` + +### Une surcouche typée de JavaScript + +Quel est le rapport entre JavaScript et TypeScript ? + +#### Syntaxe + +TypeScript est une _surcouche_ de JavaScript : une syntaxe JS légale est donc une syntaxe TS légale. +La syntaxe définit la façon dont on écrit un programme. +Par exemple, ce code a une erreur de _syntaxe_ parce qu'il manque un `)` : + +```ts twoslash +// @errors: 1005 +let a = (4 +``` + +TypeScript ne considère pas forcément du code JavaScript comme du code invalide. +Cela signifie que vous pouvez prendre du code JavaScript fonctionnel et le mettre dans un fichier TypeScript sans vous inquiéter de comment il est écrit exactement. + +#### Types + +Cependant, TypeScript est une surcouche _typée_. Cela veut dire que TS ajoute des règles régissant comment différents types de valeurs peuvent être utilisés. +L'erreur à propos de `obj.heigth` n'est pas une erreur de _syntaxe_ : c'est une erreur où l'on a utilisé une sorte de valeur (un _type_) de façon incorrecte. + +Autre exemple, ce code JavaScript que vous pouvez lancez dans votre navigateur. Il _va_ afficher une valeur : + +```js +console.log(4 / []); +``` + +Ce programme - dont la syntaxe est correcte - affiche `Infinity`. +Mais TypeScript considère que la division d'un nombre par un tableau ne fait pas sens, et va lancer une erreur : + +```ts twoslash +// @errors: 2363 +console.log(4 / []); +``` + +Il se peut que vous vouliez _vraiment_ diviser un nombre par un tableau, peut-être juste pour voir le résultat, mais la plupart du temps, vous avez fait une erreur. +Le vérificateur de types de TS est conçu pour accepter les programmes valides, tout en signalant le plus d'erreurs communes possibles. +(Nous apprendrons plus tard divers paramètres pour contrôler à quel point vous voulez que TS soit strict avec votre code.) + +En migrant du code JavaScript vers un fichier TypeScript, il se peut que vous voyiez des _erreurs de type_ en fonction de la façon avec laquelle il a été écrit. +Il se peut qu'il y ait de vrais problèmes avec votre code, tout comme il se peut que TypeScript soit trop strict. +À travers ce guide, nous montrerons comment ajouter de la syntaxe TypeScript pour éliminer ces erreurs. + +#### Comportement à l'exécution + +TypeScript est aussi un langage qui préserve le _comportement à l'exécution_ de JavaScript. +Par exemple, la division par 0 produit `Infinity` au lieu de lancer une erreur. +TypeScript, par principe, ne change **jamais** le comportement de code JS. + +Cela veut dire que si vous déplacez du code de JavaScript à TypeScript, il est **garanti** de s'exécuter de la même façon, même si TS pense qu'il comporte des erreurs liées aux types. + +La conservation du comportement à l'exécution est l'un des principes fondamentaux de TypeScript parce que cela signifie que vous pouvez facilement alterner entre les deux langages sans vous inquiéter de différences subtiles qui empêcheraient votre programme de se lancer. + + + +#### Effacement de types + +Grossièrement, une fois que le compilateur de TypeScript a fini de vérifier le code, il _efface_ les types pour laisser le code résultant. +Cela signifie qu'à la fin du processus de compilation, le code JS ne conserve aucune information de types. + +Cela signifie aussi que TypeScript, en se basant sur les types présents dans le code, n'altère jamais le _comportement_ du programme. + +Pour résumer, même si vous pouvez avoir des erreurs de type lors de la compilation, le système de types n'affecte aucunement la façon dont votre programme s'exécute. + +Enfin, TypeScript ne fournit aucune librairie supplémentaire. +Vos programmes utiliseront les mêmes librairies standard ou externes que vos programmes JS, il n'y a donc aucun framework additionnel à apprendre au niveau de TS. + +Il est intéressant de noter qu'il est possible de préciser la version de JavaScript que TypeScript doit cibler lors de la compilation. Cela affecte le code final, qui contiendra ou non des _polyfills_ (du code qui redéfinit des fonctionnalités existantes dans une version de JavaScript mais absentes dans une autre). + + + +## Apprendre JavaScript et TypeScript + +Une question souvent posée est "Est-ce que je dois apprendre TypeScript ou JavaScript", à laquelle on répond qu'il n'est pas possible d'apprendre le TS sans apprendre le JS. + +TypeScript possède la même syntaxe, et se comporte de la même façon que JavaScript, donc vous pourrez utiliser tout ce que vous apprenez avec JavaScript, dans TypeScript. + +Il y a beaucoup, _beaucoup_ de ressources disponibles pour apprendre le JavaScript. Ces ressources ne doivent pas être ignorées si vous voulez apprendre TypeScript. Par exemple, il y a à peu près 20 fois plus de questions StackOverflow taggées `javascript` que `typescript`, mais toutes les questions `javascript` s'appliquent aussi à TypeScript. + +Si vous recherchez quelque chose comme "comment trier un tableau en TypeScript", souvenez-vous : **TypeScript est du JavaScript avec un vérificateur de types à la compilation**. La façon dont vous triez un tableau en JavaScript est la même qu'en TypeScript. +Si vous trouvez une ressource qui utilise TypeScript, ce n'est pas plus mal, mais ne croyez pas que vous avez besoin de réponses spécifiques à TS pour des tâches JS de tous les jours. + +## Prochaines étapes + +C'était un bref résumé des syntaxes et outils utilisés dans le TypeScript de tous les jours. À partir de là, vous pourrez : + +- Apprendre des fondamentaux de TypeScript. Nous recommandons : + + - [Les ressources JavaScript de Microsoft](https://docs.microsoft.com/javascript/) ou + - [Le guide JavaScript dans les Mozilla Web Docs](https://developer.mozilla.org/docs/Web/JavaScript/Guide) + +- Continuer vers la page [TypeScript pour les développeurs JavaScript](/docs/handbook/typescript-in-5-minutes.html) +- Lire le Manuel [du début à la fin](/docs/handbook/intro.html) (30m) +- Explorer les [exemples du bac à sable](/play#show-examples) + + + diff --git a/docs/documentation/ko/declaration-files/By Example.md b/docs/documentation/ko/declaration-files/By Example.md index e73f5066..6e20b592 100644 --- a/docs/documentation/ko/declaration-files/By Example.md +++ b/docs/documentation/ko/declaration-files/By Example.md @@ -26,12 +26,12 @@ oneline: "How to create a d.ts file for a module" ## 프로퍼티를 갖는 객체 (Objects with Properties) -_문서_ +*문서* > 전역 변수 `myLib`에는 인사말을 만드는 함수 `makeGreeting`와, > 지금까지 생성한 인사말의 수를 가리키는 `numberOfGreetings` 프로퍼티가 있습니다. -_코드_ +*코드* ```ts let result = myLib.makeGreeting("hello, world"); @@ -40,7 +40,7 @@ console.log("The computed greeting is:" + result); let count = myLib.numberOfGreetings; ``` -_선언_ +*선언* 점 표기법으로 접근하는 타입이나 값을 설명하기 위해 `declare namespace`를 사용하세요. @@ -53,11 +53,11 @@ declare namespace myLib { ## 오버로드된 함수 (Overloaded Functions) -_문서_ +*문서* `getWidget` 함수는 숫자를 인자로 받아 Widget을 반환하거나, 문자열을 인자로 받아 Widget 배열을 반환합니다. -_코드_ +*코드* ```ts let x: Widget = getWidget(43); @@ -65,7 +65,7 @@ let x: Widget = getWidget(43); let arr: Widget[] = getWidget("all of them"); ``` -_선언_ +*선언* ```ts declare function getWidget(n: number): Widget; @@ -74,7 +74,7 @@ declare function getWidget(s: string): Widget[]; ## 재사용 가능한 타입 (인터페이스) (Reusable Types (Interfaces)) -_문서_ +*문서* > greeting을 명시할 때, 반드시 `GreetingSettings` 객체를 전달해야 합니다. > 이 객체는 다음의 프로퍼티를 갖고 있습니다: @@ -85,7 +85,7 @@ _문서_ > > 3 - color: 선택적 문자열, 예. '#ff00ff' -_코드_ +*코드* ```ts greet({ @@ -94,7 +94,7 @@ greet({ }); ``` -_선언_ +*선언* 프로퍼티를 갖는 타입을 정의하기 위해 `interface`를 사용하세요. @@ -110,11 +110,11 @@ declare function greet(setting: GreetingSettings): void; ## 재사용 가능한 타입 (타입 별칭) (Reusable Types (Type Aliases)) -_문서_ +*문서* > 인사말이 예상되는 어느 곳에나, `string`, `string`을 반환하는 함수, 또는 `Greeter` 인스턴스를 전달할 수 있습니다. -_코드_ +*코드* ```ts function getGreeting() { @@ -127,7 +127,7 @@ greet(getGreeting); greet(new MyGreeter()); ``` -_선언_ +*선언* 타입에 대한 약칭으로 타입 별칭을 사용할 수 있습니다: @@ -139,12 +139,12 @@ declare function greet(g: GreetingLike): void; ## 타입 구조화하기 (Organizing Types) -_문서_ +*문서* > `greeter` 객체는 파일에 로그를 작성하거나 경고 창을 띄울 수 있습니다. > 로그 옵션을 `.log(...)` 내부에, 경고 창 옵션을 `.alert(...)` 내부에 전달할 수 있습니다. -_코드_ +*코드* ```ts const g = new Greeter("Hello"); @@ -152,7 +152,7 @@ g.log({ verbose: true }); g.alert({ modal: false, title: "Current Greeting" }); ``` -_선언_ +*선언* 타입을 구조화하기 위해 네임스페이스를 사용하세요. @@ -187,11 +187,11 @@ declare namespace GreetingLib.Options { ## 클래스 (Classes) -_문서_ +*문서* > `Greeter` 객체를 인스턴스화해서 greeter를 생성하거나, 이 객체를 상속해서 커스텀 greeter를 생성할 수 있습니다. -_코드_ +*코드* ```ts const myGreeter = new Greeter("hello, world"); @@ -205,7 +205,7 @@ class SpecialGreeter extends Greeter { } ``` -_선언_ +*선언* 클래스 혹은 클래스-같은 객체를 설명하기 위해 `declare class`를 사용하세요. 클래스는 생성자 뿐만 아니라 프로퍼티와 메서드를 가질 수 있습니다. @@ -221,17 +221,17 @@ declare class Greeter { ## 전역 변수 (Global Variables) -_문서_ +*문서* > 전역 변수 `foo`는 존재하는 위젯의 수를 포함합니다. -_코드_ +*코드* ```ts console.log("Half the number of widgets is " + (foo / 2)); ``` -_선언_ +*선언* 변수를 선언하기 위해 `declare var`를 사용하세요. 만약 변수가 읽기-전용이라면, `declare const`를 사용하세요. @@ -244,17 +244,17 @@ declare var foo: number; ## 전역 함수 (Global Functions) -_문서_ +*문서* > 사용자에게 인사말을 보여주기 위해 `greet` 함수를 호출할 수 있습니다. -_코드_ +*코드* ```ts greet("hello, world"); ``` -_선언_ +*선언* 함수를 선언하기 위해 `declare function`을 사용하세요. diff --git a/docs/documentation/ko/get-started/TS for Functional Programmers.md b/docs/documentation/ko/get-started/TS for Functional Programmers.md index fc77b708..a4c7d0c1 100644 --- a/docs/documentation/ko/get-started/TS for Functional Programmers.md +++ b/docs/documentation/ko/get-started/TS for Functional Programmers.md @@ -44,12 +44,13 @@ C++ 달리 TypeScript는 후위 타입을 사용합니다, 예를 들면: `strin ## 내장 타입 (Built-in types) -JavaScript에서는 7개의 내장 타입을 정의합니다: +JavaScript에서는 8개의 내장 타입을 정의합니다: | 타입 | 설명 | | ----------- | ------------------------------------------- | | `Number` | 배정밀도 IEEE 754 부동소수점. | | `String` | 수정 불가능한 UTF-16 문자열. | +| `BigInt` | 임의 정밀도 형식의 정수. | | `Boolean` | `true` 와 `false`. | | `Symbol` | 보통 키로 사용하는 고유한 값. | | `Null` | 단위 타입과 동등. | @@ -62,6 +63,7 @@ TypeScript에는 기본 내장된 타입에 해당하는 원시 타입이 있습 * `number` * `string` +* `bigint` * `boolean` * `symbol` * `null` @@ -251,9 +253,9 @@ type Conflicting = { a: number } & { a: string }; `a` 와 `b` 두 개의 속성을 가지고 있습니다. 교집합과 유니언은 재귀적인 케이스에서 충돌을 일으켜서 `Conflicting.a: number & string` 입니다. -## 유니언 타입 (Unit types) +## 유닛 타입 (Unit types) -유니언 타입은 정확히 하나의 원시 값을 포함하고 있는 원시 타입의 서브타입입니다. +유닛 타입은 정확히 하나의 원시 값을 포함하고 있는 원시 타입의 서브타입입니다. 예를 들면, 문자열 `"foo"` 는 타입 `"foo"`를 가지고 있습니다. JavaScript는 내장된 enum이 없기 때문에 잘 알려진 문자열 세트를 대신해서 쓰는게 흔합니다. @@ -364,7 +366,7 @@ type Size = [number, number]; let x: Size = [101.1, 999.9]; ``` -`newtype`과 가장 유사한 것은 _태그된 교차 타입(tagged intersection)_ 입니다: +`newtype`과 가장 유사한 것은 *태그된 교차 타입(tagged intersection)* 입니다: ```ts type FString = string & { __compileTimeOnly: any }; @@ -460,7 +462,7 @@ TypeScript는 일반적으로 인자 타입에 기반하여 호출로부터 타 왜냐하면 TypeScript는 구조적이기 때문에, 이름 기반의 시스템만큼 타입 매개 변수를 필요로 하지 않습니다. 특히 함수를 다형성으로 만들 필요는 없습니다. 타입 매개변수는 매개변수를 같은 타입으로 -제한하는 것처럼 타입 정보를 _전파하는데만_ +제한하는 것처럼 타입 정보를 *전파하는데만* 쓰여야 합니다: ```ts @@ -532,7 +534,7 @@ function g() { } ## `readonly` 와 `const` (`readonly` and `const`) JavaScript에서, 수정 가능함이 기본이지만, -_참조_가 수정 불가능함을 선언하기 위해 `const`로 변수를 선언할 수 있습니다. +*참조*가 수정 불가능함을 선언하기 위해 `const`로 변수를 선언할 수 있습니다. 참조 대상은 여전히 수정 가능합니다: ```js diff --git a/docs/documentation/ko/get-started/TS for JS Programmers.md b/docs/documentation/ko/get-started/TS for JS Programmers.md index 98c96c1e..2c65db89 100644 --- a/docs/documentation/ko/get-started/TS for JS Programmers.md +++ b/docs/documentation/ko/get-started/TS for JS Programmers.md @@ -120,7 +120,7 @@ function deleteUser(user: User) { } ``` -JavaScript에서 사용할 수 있는 적은 종류의 원시 타입이 이미 있습니다.: `boolean`, `bigint`, `null`, `number`, `string`, `symbol`, `object`와 `undefined`는 인터페이스에서 사용할 수 있습니다. TypeScript는 몇 가지를 추기해 목록을 확장합니다. 예를 들어, `any` (무엇이든 허용합니다), [`unknown`](/en/play#example/unknown-and-never) (이 타입을 사용하는 사람이 타입이 무엇인지 선언했는가를 확인하십시오), [`never`](/en/play#example/unknown-and-never) (이 타입은 발생될 수 없습니다) `void` (`undefined`를 리턴하거나 리턴 값이 없는 함수). +JavaScript에서 사용할 수 있는 적은 종류의 원시 타입이 이미 있습니다.: `boolean`, `bigint`, `null`, `number`, `string`, `symbol`, `object`와 `undefined`는 인터페이스에서 사용할 수 있습니다. TypeScript는 몇 가지를 추가해 목록을 확장합니다. 예를 들어, `any` (무엇이든 허용합니다), [`unknown`](/en/play#example/unknown-and-never) (이 타입을 사용하는 사람이 타입이 무엇인지 선언했는가를 확인하십시오), [`never`](/en/play#example/unknown-and-never) (이 타입은 발생될 수 없습니다) `void` (`undefined`를 리턴하거나 리턴 값이 없는 함수). 타입을 구축하기 위한 두 가지 구문이 있다는 것을 꽤 빠르게 알 수 있을 것입니다.: [Interfaces and Types](/play/?e=83#example/types-vs-interfaces) - `interface`를 우선적으로 사용하고 특정 기능이 필요할 때 `type`을 사용해야 합니다. @@ -137,7 +137,7 @@ JavaScript에서 사용할 수 있는 적은 종류의 원시 타입이 이미 type MyBool = true | false; ``` -_참고:_ `MyBool`위에 마우스를 올린다면, `boolean`으로 분류된 것을 볼 수 있습니다 - 구조적 타입 시스템의 프로퍼티며, 나중에 살펴보겠습니다. +*참고:* `MyBool`위에 마우스를 올린다면, `boolean`으로 분류된 것을 볼 수 있습니다 - 구조적 타입 시스템의 프로퍼티며, 나중에 살펴보겠습니다. 유니언 타입이 가장 많이 사용된 사례 중 하나는 값이 다음과 같이 허용되는 `string` 또는 `number`의 [리터럴](/docs/handbook/literal-types.html)집합을 설명하는 것입니다: @@ -214,7 +214,7 @@ backpack.add(23); ## 구조적 타입 시스템 (Structural Type System) -TypeScript의 핵심 원칙 중 하나는 타입 검사가 값이 있는 _형태_에 집중한다는 것입니다. +TypeScript의 핵심 원칙 중 하나는 타입 검사가 값이 있는 *형태*에 집중한다는 것입니다. 이는 때때로 "덕 타이핑(duck typing)" 또는 "구조적 타이핑" 이라고 불립니다. 구조적 타입 시스템에서 두 객체가 같은 형태를 가지면 같은 것으로 간주됩니다. diff --git a/docs/documentation/ko/get-started/TS for OOPers.md b/docs/documentation/ko/get-started/TS for OOPers.md index 14344438..cf936ea2 100644 --- a/docs/documentation/ko/get-started/TS for OOPers.md +++ b/docs/documentation/ko/get-started/TS for OOPers.md @@ -17,16 +17,16 @@ TypeScript는 이러한 개발자에게 친숙한 기능을 많이 제공하지 만약 JavaScript에 이미 익숙하지만 주로 Java또는 C#을 사용하는 프로그래머라면, 이 소개 페이지는 흔히 접할 수 있는 오해와 함정에 대한 설명에 도움을 줄 수 있습니다. TypeScript 모델이 유형화하는 방법 중 일부는 Java나 C#과 상당히 다르며, TypeScript를 학습하는 데에 있어 이 부분을 염두에 두는 것이 중요합니다. -만약 JavaScript를 처음 접하는 Java나 C# 프로그래머라면, JavaScript의 런타임 동작을 이해하기 위해 우선적으로 타입을 _제외한_ JavaScript의 일부분을 배우는 것이 좋습니다. -TypeScript는 코드를 _실행하는_ 방식을 바꾸지 않기 때문에, 실제로 무언가 동작하는 코드를 작성하기 위해서는 여전히 JavaScript가 어떻게 작동하는지 배워야 합니다! +만약 JavaScript를 처음 접하는 Java나 C# 프로그래머라면, JavaScript의 런타임 동작을 이해하기 위해 우선적으로 타입을 *제외한* JavaScript의 일부분을 배우는 것이 좋습니다. +TypeScript는 코드를 *실행하는* 방식을 바꾸지 않기 때문에, 실제로 무언가 동작하는 코드를 작성하기 위해서는 여전히 JavaScript가 어떻게 작동하는지 배워야 합니다! TypeScript가 JavaScript와 동일한 *런타임*을 사용하므로, 특정한 런타임 동작(문자열을 숫자로 변환하기, 경고 표시, 디스크에 파일 쓰기 등)을 구현하려는 리소스는 항상 TypeScript 프로그램에 똑같이 잘 적용된다는 점을 기억하는 것은 매우 중요합니다. TypeScript에 특정된 리소스에만 제한을 두지 마십시오! ## 클래스 다시 생각하기 (Rethinking the Class) -C#과 Java는 _의무적 OOP_ 언어라고 부릅니다. -이러한 언어에서 *클래스*는 코드 구성의 기본 단위일 뿐만 아니라 런타임 시 모든 데이터 _그리고_ 동작의 기본적인 컨테이너입니다. +C#과 Java는 *의무적 OOP* 언어라고 부릅니다. +이러한 언어에서 *클래스*는 코드 구성의 기본 단위일 뿐만 아니라 런타임 시 모든 데이터 *그리고* 동작의 기본적인 컨테이너입니다. 기능과 데이터를 전부 클래스에 담도록 강제하는 것은 일부 문제에 대해선 좋은 도메인 모델이 될 수 있지만, 모든 도메인이 이러한 방식으로 표현될 *필요*는 없습니다. ### 자유로운 함수와 데이터 (Free Functions and Data) @@ -66,7 +66,7 @@ C#과 Java에서 주어진 값과 객체는 ‘null’, 원시 타입, 또는 C# 또는 Java에서 런타임 타입과 해당 컴파일 타임 선언 사이의 일대일 대응관계는 중요합니다. TypeScript에서 타입은 공통의 무언가를 공유하는 *값의 집합*으로 생각하는 것이 좋습니다. -타입은 집합에 불과하기 때문에, 특정한 값은 동시에 _수많은_ 집합에 속할 수 있습니다. +타입은 집합에 불과하기 때문에, 특정한 값은 동시에 *수많은* 집합에 속할 수 있습니다. 일단 타입을 집합으로 생각하기 시작하면, 특정 연산이 매우 자연스러워집니다. 예를 들어, C#에서는 ‘string’과 ‘int’ *둘 다 가능한* 타입이 존재하지 않기 때문에 이 값을 인자로 전달하는 것은 이상합니다. @@ -79,7 +79,7 @@ TypeScript는 집합론에 의거해 타입을 이용하는 여러 방법을 제 ### 삭제된 구조적 타입 (Erased Structural Types) -TypeScript에서, 객체는 정확히 단일 타입이 _아닙니다_. +TypeScript에서, 객체는 정확히 단일 타입이 *아닙니다*. 예를 들어 인터페이스를 만족하는 객체를 생성할 때, 둘 사이의 선언적인 관계가 없더라도 해당 인터페이스가 예상되는 곳에 해당 객체를 사용할 수 있습니다. ``` @@ -109,13 +109,13 @@ printPoint(obj); printName(obj); ``` -TypeScript의 타입 시스템은 명목이 아닌 _구조적_입니다: `obj`는 숫자인 `x`와 `y` 프로퍼티를 가지고 있으므로, `Pointlike`로써 사용될 수 있습니다. +TypeScript의 타입 시스템은 명목이 아닌 *구조적*입니다: `obj`는 숫자인 `x`와 `y` 프로퍼티를 가지고 있으므로, `Pointlike`로써 사용될 수 있습니다. 타입 간의 관계는 특정 관계로 선언되었는지가 아닌, 포함된 프로퍼티에 의해 결정됩니다. -TypeScript의 타입 시스템은 또한 _구체화되지 않았습니다_: 런타임에 `obj`가 `Pointlike`임을 알려주지 않습니다. -사실, `Pointlike` 타입은 런타임에 _어떤 형태로도_ 존재하지 않습니다. +TypeScript의 타입 시스템은 또한 *구체화되지 않았습니다*: 런타임에 `obj`가 `Pointlike`임을 알려주지 않습니다. +사실, `Pointlike` 타입은 런타임에 *어떤 형태로도* 존재하지 않습니다. -_집합으로서의 타입_ 개념으로 보면, `obj`를 `Pointlike` 값 집합이나 `Named` 값 집합의 멤버로 간주할 수 있습니다. +*집합으로서의 타입* 개념으로 보면, `obj`를 `Pointlike` 값 집합이나 `Named` 값 집합의 멤버로 간주할 수 있습니다. ### 구조적 타입화의 결과 (Consequences of Structural Typing) @@ -123,7 +123,7 @@ _집합으로서의 타입_ 개념으로 보면, `obj`를 `Pointlike` 값 집합 #### 빈 타입 (Empty Types) -첫 번째로 _빈 타입_은 예상을 무시하는 것처럼 보입니다: +첫 번째로 *빈 타입*은 예상을 무시하는 것처럼 보입니다: ``` class Empty {} @@ -138,11 +138,11 @@ fn({ k: 10 }); TypeScript는 주어진 인수가 유효한 `Empty`인지 확인하여 `fn`의 호출이 유효한지를 검사합니다 `{ k: 10 }`과 `class Empty { }`의 _구조를 확인하여 유효성을 검사합니다. -`Empty`에 프로퍼티가 없으므로 `Empty`가 수행하는 _모든_ 프로퍼티가 `{ k: 10 }`에 속해있습니다. +`Empty`에 프로퍼티가 없으므로 `Empty`가 수행하는 *모든* 프로퍼티가 `{ k: 10 }`에 속해있습니다. 그러므로, 유효한 호출입니다: 놀랍지만, 최종적으로 명목적인 객체지향프로그래밍 언어와 매우 비슷하게 사용됩니다. -파생 클래스와 파생 클래스의 기본 사이의 자연스러운 하위 타입 관계가 파괴되기 때문에, 하위 클래스는 _삭제_할 수 없습니다. +파생 클래스와 파생 클래스의 기본 사이의 자연스러운 하위 타입 관계가 파괴되기 때문에, 하위 클래스는 *삭제*할 수 없습니다. 구조적 타입 시스템은 호환 가능한 유형의 속성을 갖는 측면에서 하위 타입을 설명하므로 위의 관계를 암시적으로 구별합니다 #### 동일한 타입 (Identical Types) @@ -165,7 +165,7 @@ class Golfer { let w: Car = new Golfer(); ``` -다시 말하지만, 오류가 아닌 이유는 클래스의 _구조_가 동일하기 때문입니다. +다시 말하지만, 오류가 아닌 이유는 클래스의 *구조*가 동일하기 때문입니다. 잠재적인 혼란의 이유가 될 수도 있겠지만, 사실 상관없는 클래스가 동일한 경우는 일반적이지 않습니다. 차후에 클래스 챕터에서 클래스가 서로 어떻게 관련되는지에 대해 자세히 알아볼 것입니다. diff --git a/docs/documentation/ko/get-started/TS for the New Programmer.md b/docs/documentation/ko/get-started/TS for the New Programmer.md index 17d74460..11d89dda 100644 --- a/docs/documentation/ko/get-started/TS for the New Programmer.md +++ b/docs/documentation/ko/get-started/TS for the New Programmer.md @@ -20,16 +20,16 @@ JavaScript가 처음 나왔을 때, 수십 줄 이상의 코드를 작성하는 웹 브라우저 개발자들은 위와 같이 늘어나는 JS 사용량에 대하여 실행 엔진(동적 컴파일)을 최적화시키고 최적화 된 것을 이용해 할 수 있는 일(API 추가)을 확장하여 웹 개발자가 더 많이 JS를 사용할 수 있게 했습니다. 현대 웹사이트에서, 브라우저는 수십만 줄의 코드로 구성된 어플리케이션을 자주 실행합니다. -이는 정적 페이지의 간단한 네트워크로 시작해서, 모든 종류의 만족스러울만한 _어플리케이션_을 위한 플랫폼으로 성장한 "웹"의 길고 점진적인 성장입니다. +이는 정적 페이지의 간단한 네트워크로 시작해서, 모든 종류의 만족스러울만한 *어플리케이션*을 위한 플랫폼으로 성장한 "웹"의 길고 점진적인 성장입니다. 이외에도, JS는 node.js를 사용하여 JS 서버들을 구현하는 것처럼, 브라우저 맥락에서 벗어나는 일에 사용하기 충분할 정도로 유명해졌습니다. "어디서든 작동됨"과 같은 JS의 성질은 교차 플랫폼(cross-platform) 개발을 위한 매력적인 선택지이기도 합니다. -오늘날 많은 개발자들은 _오직_ JavaScript만을 이용하여 전체 스택을 프로그래밍하고 있습니다! +오늘날 많은 개발자들은 *오직* JavaScript만을 이용하여 전체 스택을 프로그래밍하고 있습니다! 요약하자면, 우리에게는 빠른 사용을 위해 설계되었으며 수백만 줄의 어플리케이션들을 작성하기 위해 만들어진 완벽한 도구인 JavaScript가 있습니다. -모든 언어는 각자의 _별난 점_ - 이상한 점과 놀랄만한 점이 있으며, JavaScript의 자랑스럽지만은 않은 시작은 _많은_ 문제를 만들게 되었습니다. 예를 들어: +모든 언어는 각자의 *별난 점* - 이상한 점과 놀랄만한 점이 있으며, JavaScript의 자랑스럽지만은 않은 시작은 *많은* 문제를 만들게 되었습니다. 예를 들어: -* JavaScript의 동일 연산자는 (`==`) 인수를 _강제로 변환하여(coerces)_, 예기치 않은 동작을 유발합니다: +* JavaScript의 동일 연산자는 (`==`) 인수를 *강제로 변환하여(coerces)*, 예기치 않은 동작을 유발합니다: ```js if ("" == 0) { @@ -54,11 +54,11 @@ JavaScript가 처음 나왔을 때, 수십 줄 이상의 코드를 작성하는 ## TypeScript: 정적 타입 검사자 (TypeScript: A Static Type Checker) 앞서 몇 언어는 버그가 많은 프로그램을 아예 실행시키지 않는다고 했습니다. -프로그램을 실행시키지 않으면서 코드의 오류를 검출하는 것을 _정적 검사_라고 합니다. -어떤 것이 오류인지와 어떤 것이 연산 되는 값에 기인하지 않음을 정하는 것이 정적 _타입_ 검사입니다. +프로그램을 실행시키지 않으면서 코드의 오류를 검출하는 것을 *정적 검사*라고 합니다. +어떤 것이 오류인지와 어떤 것이 연산 되는 값에 기인하지 않음을 정하는 것이 정적 *타입* 검사입니다. -_정적 타입 검사자_인 TypeScript는 프로그램을 실행시키기 전에 _값의 종류_를 기반으로 프로그램의 오류를 찾습니다. -예를 들어, 위의 마지막 예시에 오류가 있는 이유는 `obj`의 _타입_ 때문입니다. +*정적 타입 검사자*인 TypeScript는 프로그램을 실행시키기 전에 *값의 종류*를 기반으로 프로그램의 오류를 찾습니다. +예를 들어, 위의 마지막 예시에 오류가 있는 이유는 `obj`의 *타입* 때문입니다. 다음은 TypeScript에서 볼 수 있는 오류입니다: ``` @@ -73,9 +73,9 @@ const area = obj.width * obj.heigth; #### 구문 (Syntax) -TypeScript는 JS의 구문이 허용되는, JavaScript의 _상위 집합_ 언어입니다. +TypeScript는 JS의 구문이 허용되는, JavaScript의 *상위 집합* 언어입니다. 구문은 프로그램을 만들기 위해 코드를 작성하는 방법을 의미합니다. -예를 들어, 다음 코드는 `)`이 없으므로 _구문_ 오류입니다: +예를 들어, 다음 코드는 `)`이 없으므로 *구문* 오류입니다: ``` // @errors: 1005 @@ -87,10 +87,10 @@ TypeScript는 독특한 구문 때문에 JavaScript 코드를 오류로 보지 #### 타입 (Types) -그러나 TypeScript는 다른 종류의 값들을 사용할 수 있는 방법이 추가된, _타입이 있는_ 상위 집합입니다. -위의 `obj.heigth` 오류는 _구문_ 오류가 아닌, 값의 종류(_타입_)를 잘못 사용해서 생긴 오류입니다. +그러나 TypeScript는 다른 종류의 값들을 사용할 수 있는 방법이 추가된, *타입이 있는* 상위 집합입니다. +위의 `obj.heigth` 오류는 *구문* 오류가 아닌, 값의 종류(*타입*)를 잘못 사용해서 생긴 오류입니다. -또 다른 예시로, 아래와 같은 JavaScript 코드가 브라우저에서 실행될 때, 다음과 같은 값이 출력될 _것입니다_: +또 다른 예시로, 아래와 같은 JavaScript 코드가 브라우저에서 실행될 때, 다음과 같은 값이 출력될 *것입니다*: ```js console.log(4 / []); @@ -104,17 +104,17 @@ console.log(4 / []); console.log(4 / []); ``` -실제로 어떤 일이 일어나는지 보려는 의도로 숫자를 배열로 나눌 수 _있지만_, 대부분은 프로그래밍 실수입니다. +실제로 어떤 일이 일어나는지 보려는 의도로 숫자를 배열로 나눌 수 *있지만*, 대부분은 프로그래밍 실수입니다. TypeScript의 타입 검사자는 일반적인 오류를 최대한 많이 검출하면서 올바른 프로그램을 만들 수 있게 설계되었습니다. (나중에 TypeScript가 코드를 얼마나 엄격하게 검사할 수 있는지에 대한 설정에 대해 알아봅시다.) -만약 JavaScript 파일의 코드를 TypeScript 코드로 옮기면, 코드를 어떻게 작성했는지에 따라 _타입 오류_를 볼 수 있습니다. +만약 JavaScript 파일의 코드를 TypeScript 코드로 옮기면, 코드를 어떻게 작성했는지에 따라 *타입 오류*를 볼 수 있습니다. 이는 코드 상의 문제이거나, TypeScript가 지나치게 보수적인 것일 수 있습니다. 위와 같은 오류를 제거하기 위해 가이드는 다양한 TypeScript 구문을 추가하는 방법을 보여줍니다. #### 런타임 특성 (Runtime Behavior) -TypeScript는 JavaScript의 _런타임 특성_을 가진 프로그래밍 언어입니다. +TypeScript는 JavaScript의 *런타임 특성*을 가진 프로그래밍 언어입니다. 예를 들어, JavaScript에서 0으로 나누는 행동은 런타임 예외로 처리하지 않고 `Infinity`값을 반환합니다. 논리적으로, TypeScript는 JavaScript 코드의 런타임 특성을 **절대** 변화시키지 않습니다. @@ -130,10 +130,10 @@ how JS code can be used in TS.) #### 삭제된 타입 (Erased Types) -개략적으로, TypeScript의 컴파일러가 코드 검사를 마치면 타입을 _삭제해서_ 결과적으로 "컴파일된" 코드를 만듭니다. +개략적으로, TypeScript의 컴파일러가 코드 검사를 마치면 타입을 *삭제해서* 결과적으로 "컴파일된" 코드를 만듭니다. 즉 코드가 한 번 컴파일되면, 결과로 나온 일반 JS 코드에는 타입 정보가 없습니다. -타입 정보가 없는 것은 TypeScript가 추론한 타입에 따라 프로그램의 _특성_을 변화시키지 않는다는 의미입니다. +타입 정보가 없는 것은 TypeScript가 추론한 타입에 따라 프로그램의 *특성*을 변화시키지 않는다는 의미입니다. 결론적으로 컴파일 도중에는 타입 오류가 표출될 수 있지만, 타입 시스템 자체는 프로그램이 실행될 때 작동하는 방식과 관련이 없습니다. 마지막으로, TypeScript는 추가 런타임 라이브러리를 제공하지 않습니다. @@ -153,8 +153,8 @@ that this document is maintained.) 정답은 JavaScript를 배우지 않고선 TypeScript를 배울 수 없다는 것입니다! TypeScript는 JavaScript와 구문과 런타임 특성을 공유하므로, JavaScript에서 배운 모든 것들은 동시에 TypeScript를 배울 때 도움이 될 것입니다. -프로그래머들을 위한 JavaScript 학습 자원이 많습니다; TypeScript를 작성할 때 그런 학습 자원을 무시해선 _안됩니다_. -예를 들어 `javascript`태그가 붙은 질문이 `typescript`태그가 붙은 질문보다 약 20배는 많지만, _모든_ `javascript`질문은 TypeScript에도 적용할 수 있습니다. +프로그래머들을 위한 JavaScript 학습 자원이 많습니다; TypeScript를 작성할 때 그런 학습 자원을 무시해선 *안됩니다*. +예를 들어 `javascript`태그가 붙은 질문이 `typescript`태그가 붙은 질문보다 약 20배는 많지만, *모든* `javascript`질문은 TypeScript에도 적용할 수 있습니다. 만약 "TypeScript에서 리스트를 정렬하는 법"과 같은 것을 찾는 경우, 기억하세요: **TypeScript는 컴파일-타임 타입 검사자가 있는 JavaScript의 런타임입니다**. 리스트를 TypeScript에서 정렬하는 방법은 JavaScript에서 똑같은 방법으로 할 수 있습니다. diff --git a/docs/documentation/ko/handbook-v2/Basics.md b/docs/documentation/ko/handbook-v2/Basics.md index 3cbe8e67..6d408066 100644 --- a/docs/documentation/ko/handbook-v2/Basics.md +++ b/docs/documentation/ko/handbook-v2/Basics.md @@ -49,7 +49,7 @@ TypeError: message is not a function 이와 같은 실수를 미리 방지할 수 있다면 참 좋을 것 같습니다. -JavaScript 런타임은 코드가 실행될 때 자신이 무엇을 해야 할지 결정하기 위하여 값의 _타입_, 즉 해당 값이 어떤 동작과 능력을 가지고 있는지를 확인합니다. +JavaScript 런타임은 코드가 실행될 때 자신이 무엇을 해야 할지 결정하기 위하여 값의 *타입*, 즉 해당 값이 어떤 동작과 능력을 가지고 있는지를 확인합니다. 이것이 바로 `TypeError`가 암시하는 바입니다. 위 예시에서는 문자열인 `"Hello World"`가 함수로서 호출될 수 없다고 말하고 있는 것이죠. 일부 값들, 이를테면 `string`과 `number`과 같은 원시 타입의 값의 경우 `typeof` 연산자를 사용하면 각 값들의 타입을 실행 시점에 알 수 있습니다. @@ -62,28 +62,28 @@ function fn(x) { } ``` -위 코드를 보면, 인자로 전달된 객체가 호출 가능한 프로퍼티인 `flip`을 가져야만 위 함수가 잘 작동할 것이라는 것을 우리는 코드를 읽음으로써 _알 수 있습니다._ 하지만 JavaScript는 우리가 알고 있는 이러한 정보를 코드가 실행되는 동안 알지 못합니다. +위 코드를 보면, 인자로 전달된 객체가 호출 가능한 프로퍼티인 `flip`을 가져야만 위 함수가 잘 작동할 것이라는 것을 우리는 코드를 읽음으로써 *알 수 있습니다.* 하지만 JavaScript는 우리가 알고 있는 이러한 정보를 코드가 실행되는 동안 알지 못합니다. 순수 JavaScript에서 `fn`가 특정 값과 어떤 동작을 수행하는지 알 수 있는 유일한 방법은 호출하고 무슨 일이 벌어지는지 보는 것입니다. 이와 같은 동작은 코드 실행 전에 예측을 어렵게 만듭니다. 다시 말해 코드가 어떤 동작 결과를 보일지 코드를 작성하는 동안에는 알기 어렵습니다. -이런 측면에서 볼 때, _타입_이란 어떤 값이 `fn`으로 전달될 수 있고, 어떤 값은 실행에 실패할 것임을 설명하는 개념입니다. -JavaScript는 오직 _동적_ 타입만을 제공하며, 코드를 실행해야만 어떤 일이 벌어지는지 비로소 확인할 수 있습니다. +이런 측면에서 볼 때, *타입*이란 어떤 값이 `fn`으로 전달될 수 있고, 어떤 값은 실행에 실패할 것임을 설명하는 개념입니다. +JavaScript는 오직 *동적* 타입만을 제공하며, 코드를 실행해야만 어떤 일이 벌어지는지 비로소 확인할 수 있습니다. -이에 대한 대안은 _정적_ 타입 시스템을 사용하여 코드가 실행되기 _전에_ 코드에 대하여 예측하는 것입니다. +이에 대한 대안은 *정적* 타입 시스템을 사용하여 코드가 실행되기 *전에* 코드에 대하여 예측하는 것입니다. ## 정적 타입 검사 앞서 살펴본, `string`을 함수로서 호출하고자 했을 때 얻은 `TypeError`의 이야기로 돌아가 봅시다. -_대부분의 사람들은_ 코드를 실행했을 때 오류를 보고 싶지 않습니다. 그것은 버그로 여겨집니다! +*대부분의 사람들은* 코드를 실행했을 때 오류를 보고 싶지 않습니다. 그것은 버그로 여겨집니다! 그리고 새로운 코드를 작성할 때 우리는 새로운 버그를 만들어내지 않도록 최선을 다합니다. 여기서 만약 약간의 코드를 추가하고 파일을 저장한 뒤, 코드를 다시 실행했을 때 바로 오류가 확인된다면, 문제를 신속하게 격리시킬 수 있을 것입니다. 하지만 항상 그렇게 되는 것은 아닙니다. 기능을 충분히 테스트하지 않아서, 잠재적인 오류를 미처 발견하지 못할 수도 있습니다! 또는 운 좋게 오류를 발견했더라도, 결국 상당한 규모의 리팩토링을 거치고 새 코드를 추가하면서 의도치 않게 코드를 깊게 파헤치게 될 수도 있습니다. -이상적으로는, 코드를 실행하기 _전에_ 이러한 버그를 미리 발견할 수 있는 도구가 있다면 좋을 것입니다. +이상적으로는, 코드를 실행하기 *전에* 이러한 버그를 미리 발견할 수 있는 도구가 있다면 좋을 것입니다. TypeScript와 같은 정적 타입 검사기의 역할이 바로 그것입니다. -_정적 타입 시스템_은 우리가 작성한 프로그램에서 사용된 값들의 형태와 동작을 설명합니다. +*정적 타입 시스템*은 우리가 작성한 프로그램에서 사용된 값들의 형태와 동작을 설명합니다. TypeScript와 같은 타입 검사기는 이 정보를 활용하여 프로그램이 제대로 작동하지 않을 때 우리에게 알려줍니다. ```ts twoslash @@ -127,7 +127,7 @@ user.location; ``` 비록 때로는 이로 인하여 표현의 유연성을 희생해야 하겠지만, 이렇게 함으로서 명시적인 버그는 아니지만 버그로 타당히 간주되는 경우를 잡아내는 데에 그 목적이 있습니다. -그리고 TypeScript는 이러한 겉으로 드러나지 않는 버그를 _꽤 많이_ 잡아냅니다. +그리고 TypeScript는 이러한 겉으로 드러나지 않는 버그를 *꽤 많이* 잡아냅니다. 예를 들어, 오타, @@ -169,10 +169,10 @@ if (value !== "a") { ## 프로그래밍 도구로서의 타입 TypeScript는 우리가 코드 상에서 실수를 저질렀을 때 버그를 잡아줍니다. -그거 좋죠, 그런데 TypeScript는 _여기서 더 나아가서_ 우리가 실수를 저지르는 바로 그 순간 이를 막아줍니다. +그거 좋죠, 그런데 TypeScript는 *여기서 더 나아가서* 우리가 실수를 저지르는 바로 그 순간 이를 막아줍니다. 타입 검사기는 우리가 변수 또는 다른 프로퍼티 상의 올바른 프로퍼티에 접근하고 있는지 여부를 검사할 수 있도록 관련 정보들을 가지고 있습니다. -이 정보를 활용하면 타입 검사기는 우리가 사용할 수 있는 프로퍼티를 _제안_할 수 있게 됩니다. +이 정보를 활용하면 타입 검사기는 우리가 사용할 수 있는 프로퍼티를 *제안*할 수 있게 됩니다. 즉, TypeScript는 코드 수정에 활용될 수 있고, 우리가 코드를 입력할 때 오류 메시지를 제공하거나 코드 완성 기능을 제공할 수 있습니다. 이는 TypeScript에서 도구(Tooling)를 논할 때에 흔히 언급되는 내용입니다. @@ -198,7 +198,7 @@ TypeScript를 지원하는 코드 편집기는 오류를 자동으로 고쳐주 ## `tsc`, TypeScript 컴파일러 -지금까지 계속 타입 검사에 대하여 이야기했지만, 아직 타입 _검사기_를 사용하지 않았습니다. +지금까지 계속 타입 검사에 대하여 이야기했지만, 아직 타입 *검사기*를 사용하지 않았습니다. 우리의 새로운 친구 `tsc`, TypeScript 컴파일러와 첫인사를 나누도록 합시다. 우선, npm을 사용하여 설치하도록 하겠습니다. @@ -225,13 +225,13 @@ tsc hello.ts 짜잔! -잠깐, 정확히 _무엇_이 "짜잔"하고 나왔다는 것이죠? +잠깐, 정확히 *무엇*이 "짜잔"하고 나왔다는 것이죠? `tsc`를 실행했지만 아무 일도 일어나지 않았습니다! 뭐, 타입 오류가 없었으니, 아무것도 보고될 것이 없고 그래서 콘솔에도 아무런 출력이 나타나지 않았습니다. -하지만 다시 확인해보면, 우리는 그 대신 _파일_ 출력을 얻었습니다. +하지만 다시 확인해보면, 우리는 그 대신 *파일* 출력을 얻었습니다. 현재 디렉토리를 보면, `hello.ts` 파일 옆에 `hello.js` 파일이 있는 것을 볼 수 있습니다. -이것이 `tsc`가 우리의 `hello.ts` 파일을 JavaScript 파일로 _컴파일_ 또는 _변형_한 결과물입니다. +이것이 `tsc`가 우리의 `hello.ts` 파일을 JavaScript 파일로 *컴파일* 또는 *변형*한 결과물입니다. 그리고 그 내용을 확인해보면, TypeScript가 `.ts` 파일을 처리한 뒤 뱉어낸 내용을 확인할 수 있습니다. ```js @@ -243,7 +243,7 @@ console.log("Hello world!"); 컴파일러는 사람이 작성한 듯이 깔끔하고 읽을 수 있는 코드를 만들어내고자 시도합니다. 물론 그것이 항상 쉬운 것은 아니지만, TypeScript는 일관성 있게 들여 쓰기를 수행하고, 여러 줄에 걸쳐 코드가 작성되는 것을 감안하고, 코드 주변에 작성된 주석도 잘 배치해둡니다. -만약 타입 검사 오류가 _주어지면_ 어떨까요? +만약 타입 검사 오류가 *주어지면* 어떨까요? `hello.ts`를 다시 작성해보겠습니다. ```ts twoslash @@ -301,7 +301,7 @@ function greet(person: string, date: Date) { } ``` -방금 우리는 `person`과 `date`에 대하여 _타입 표기_를 수행하여 `greet`가 호출될 때 함께 사용될 수 있는 값들의 타입을 설명했습니다. +방금 우리는 `person`과 `date`에 대하여 *타입 표기*를 수행하여 `greet`가 호출될 때 함께 사용될 수 있는 값들의 타입을 설명했습니다. 해당 시그니처는 "`greet`는 `string` 타입의 `person`과 `Date` 타입의 `date`을 가진다"고 해석할 수 있습니다. 이것이 있다면, TypeScript는 우리가 해당 함수를 올바르지 못하게 사용했을 경우 이를 알려줄 수 있게 됩니다. @@ -333,7 +333,7 @@ greet("Maddison", new Date()); ``` 명시적인 타입 표기를 항상 작성할 필요는 없다는 것을 꼭 기억해두세요. -많은 경우, TypeScript는 생략된 타입 정보를 _추론할 수_ (또는 "알아낼 수") 있습니다. +많은 경우, TypeScript는 생략된 타입 정보를 *추론할 수* (또는 "알아낼 수") 있습니다. ```ts twoslash let msg = "hello there!"; @@ -364,8 +364,8 @@ greet("Maddison", new Date()); 1. `person`과 `date` 인자는 더 이상 타입 표기를 가지지 않습니다. 2. "템플릿 문자열" - 백틱(`` ` `` 문자)을 사용하여 작성된 문장 - 은 연결 연산자(`+`)로 이루어진 일반 문자열로 변환되었습니다. -두번째 항목에 대하여서는 이후 자세히 다로도록 하고 우선 첫번째 항목에 초점을 두도록 하겠습니다. -타입 표기는 JavaScript(또는 엄밀히 말하여 ECMAScript)의 일부가 아니므로, TypeScript를 수정 없이 그대로 실행할 수 있는 브라우저나 런타임을 현재 존재하지 않습니다. +두번째 항목에 대하여서는 이후 자세히 다루도록 하고 우선 첫번째 항목에 초점을 두도록 하겠습니다. +타입 표기는 JavaScript(또는 엄밀히 말하여 ECMAScript)의 일부가 아니므로, TypeScript를 수정 없이 그대로 실행할 수 있는 브라우저나 런타임은 현재 존재하지 않습니다. 이것이 TypeScript를 사용하고자 할 때 다른 무엇보다도 컴파일러가 필요한 이유입니다. TypeScript 전용 코드를 제거하거나 변환하여 실행할 수 있도록 만들 방법이 필요합니다. 대부분의 TypeScript 전용 코드는 제거되며, 마찬가지로 타입 표기 또한 완전히 지워집니다. @@ -387,9 +387,9 @@ greet("Maddison", new Date()); 왜 이러한 일이 생겼을까요? -템플릿 문자열은 ECMAScript 2015(a.k.a. ECMAScript 6, ES2015, ES6, 등. _더 묻지 마세요_)라고 불리는 버전의 ECMAScript에서 등장한 기능입니다. +템플릿 문자열은 ECMAScript 2015(a.k.a. ECMAScript 6, ES2015, ES6, 등. *더 묻지 마세요*)라고 불리는 버전의 ECMAScript에서 등장한 기능입니다. TypeScript는 새 버전의 ECMAScript의 코드를 ECMAScript 3 또는 ECMAScript 5와 같은 보다 예전 버전의 것들로 다시 작성해 줍니다. -새로운 또는 "상위" 버전의 ECMAScript를 예전의 또는 "하위" 버전의 것으로 바꾸는 과정을 _다운레벨링_이라 부르기도 합니다. +새로운 또는 "상위" 버전의 ECMAScript를 예전의 또는 "하위" 버전의 것으로 바꾸는 과정을 *다운레벨링*이라 부르기도 합니다. TypeScript는 ES3라는 아주 구버전의 ECMAScript를 타겟으로 동작하는 것이 기본 동작입니다. `--target` 플래그를 설정하면 보다 최근 버전을 타겟으로 변환을 수행할 수도 있습니다. @@ -436,5 +436,5 @@ CLI에서 `--strict` 플래그를 설정하거나 [`tsconfig.json`](https://www. ### `strictNullChecks` `null`과 `undefined`와 같은 값은 다른 타입의 값에 할당할 수 있는 것이 기본 동작입니다. -이는 코드 작성을 쉽게 만들어주지만, `null`과 `undefined`의 처리를 잊는 것은 세상의 샐 수 없이 많은 버그들의 원인입니다. 혹자는 이를 [백만 불 짜리 실수](https://www.youtube.com/watch?v=ybrQvs4x0Ps)라고 일컫기도 합니다! -`strictNullChecks` 플래그는 `null`과 `undefined`를 보다 명시적으로 처리하며, `null` 및 `undefined` 처리를 _잊었는지_ 여부를 걱정하는 데에서 우리를 _해방시켜_ 줍니다. +이는 코드 작성을 쉽게 만들어주지만, `null`과 `undefined`의 처리를 잊는 것은 세상의 셀 수 없이 많은 버그들의 원인입니다. 혹자는 이를 [백만 불 짜리 실수](https://www.youtube.com/watch?v=ybrQvs4x0Ps)라고 일컫기도 합니다! +`strictNullChecks` 플래그는 `null`과 `undefined`를 보다 명시적으로 처리하며, `null` 및 `undefined` 처리를 *잊었는지* 여부를 걱정하는 데에서 우리를 *해방시켜* 줍니다. diff --git a/docs/documentation/ko/handbook-v2/Everyday Types.md b/docs/documentation/ko/handbook-v2/Everyday Types.md index f0574def..1c0ba6cd 100644 --- a/docs/documentation/ko/handbook-v2/Everyday Types.md +++ b/docs/documentation/ko/handbook-v2/Everyday Types.md @@ -8,7 +8,7 @@ oneline: "언어의 원시 타입들." 이번 장에서는 JavaScript 코드에서 찾아볼 수 있는 가장 흔한 타입들을 다루고, 이 타입들을 TypeScript에서 어떻게 기술하는지 각각의 대응하는 방식에 대하여 설명하겠습니다. 이 문서에서 빠짐없이 전부 다루고자 하는 것이 아니며, 타입을 만들고 사용하는 더 많은 방법들은 이후 이어지는 장에서 다룰 것입니다. -타입은 단지 타입 표기 이외에도 훨씬 다양한 _위치_에 나타날 수 있습니다. +타입은 단지 타입 표기 이외에도 훨씬 다양한 *위치*에 나타날 수 있습니다. 타입 자체에 대하여 배우는 것과 더불어, 새로운 구조체를 만들고자 할 때 타입을 참조하는 경우들에 대하여 알아볼 것입니다. 우선 JavaScript 또는 TypeScript 코드를 작성할 때 가장 기본적이면서 흔히 만날 수 있는 타입들을 다시 살펴보는 데에서 시작해보겠습니다. @@ -24,15 +24,15 @@ JavaScript에서 아주 흔하게 사용되는 세 가지의 [원시 타입](htt - `number`은 `42`와 같은 숫자를 나타냅니다. JavaScript는 정수를 위한 런타임 값을 별도로 가지지 않으므로, `int` 또는 `float`과 같은 것은 존재하지 않습니다. 모든 수는 단순히 `number`입니다 - `boolean`은 `true`와 `false`라는 두 가지 값만을 가집니다 -> `String`, `Number`, `Boolean`와 같은 (대문자로 시작하는) 타입은 유효한 타입이지만, 코드상에서 이러한 특수 내장 타입을 사용하는 경우는 극히 드뭅니다. _항상_ `string`, `number`, `boolean` 타입을 사용하세요. +> `String`, `Number`, `Boolean`와 같은 (대문자로 시작하는) 타입은 유효한 타입이지만, 코드상에서 이러한 특수 내장 타입을 사용하는 경우는 극히 드뭅니다. *항상* `string`, `number`, `boolean` 타입을 사용하세요. ## 배열 `[1, 2, 3]`과 같은 배열의 타입을 지정할 때 `number[]` 구문을 사용할 수 있습니다. 이 구문은 모든 타입에서 사용할 수 있습니다(예를 들어, `string[]`은 문자열의 배열입니다). 위 타입은 `Array`와 같은 형태로 적을 수 있으며, 동일한 의미를 가집니다. -`T` 구문에 대한 내용은 _제네릭_을 다룰 때 좀 더 알아보겠습니다. +`T` 구문에 대한 내용은 *제네릭* 을 다룰 때 좀 더 알아보겠습니다. -> `[number]`는 전혀 다른 의미를 가집니다. _튜플 타입_ 부분을 참조하세요. +> `[number]`는 전혀 다른 의미를 가집니다. *튜플 타입* 부분을 참조하세요. ## `any` @@ -71,10 +71,10 @@ let myName: string = "Alice"; ``` > TypeScript는 `int x = 0;`과 같이 "타입을 왼쪽에 쓰는" 식의 표기법을 사용하지 않습니다. -> 타입 표기는 항상 타입의 대상 _뒤쪽에_ 위치합니다. +> 타입 표기는 항상 타입의 대상 *뒤쪽에* 위치합니다. 하지만 대부분의 경우, 타입 표기는 필요하지 않습니다. -가능하다면 TypeScript는 자동으로 코드 내의 있는 타입들을 _추론_하고자 시도합니다. +가능하다면 TypeScript는 자동으로 코드 내의 있는 타입들을 *추론*하고자 시도합니다. 예를 들어, 변수의 타입은 해당 변수의 초깃값의 타입을 바탕으로 추론됩니다. ```ts twoslash @@ -108,7 +108,7 @@ function greet(name: string) { ```ts twoslash // @errors: 2345 declare function greet(name: string): void; -// ---셍략--- +// ---cut--- // 만약 실행되면 런타임 오류가 발생하게 됩니다! greet(42); ``` @@ -158,13 +158,13 @@ names.forEach((s) => { 매개 변수 `s`에는 타입이 표기되지 않았음에도 불구하고, TypeScript는 `s`의 타입을 알아내기 위하여 배열의 추론된 타입과 더불어 `forEach` 함수의 타입을 활용하였습니다. -이 과정은 _문맥적 타입 부여_라고 불리는데, 왜냐하면 함수가 실행되는 _문맥_을 통하여 해당 함수가 가져야 하는 타입을 알 수 있기 때문입니다. -추론 규칙과 비슷하게, 이 과정이 어떻게 일어나는지를 명시적으로 배울 필요는 없지만, 이것이 _실제로 일어나는 과정_이라는 것을 이해하면 타입 표기가 불필요한 경우를 구분하는 데에 도움이 됩니다. +이 과정은 *문맥적 타입 부여*라고 불리는데, 왜냐하면 함수가 실행되는 *문맥*을 통하여 해당 함수가 가져야 하는 타입을 알 수 있기 때문입니다. +추론 규칙과 비슷하게, 이 과정이 어떻게 일어나는지를 명시적으로 배울 필요는 없지만, 이것이 *실제로 일어나는 과정*이라는 것을 이해하면 타입 표기가 불필요한 경우를 구분하는 데에 도움이 됩니다. 값이 발생하는 문맥이 해당 값의 타입에 영향을 끼치는 예시들은 이후에 살펴보도록 하겠습니다. ## 객체 타입 -원시 타입을 제외하고 가장 많이 마주치는 타입은 _객체 타입_입니다. +원시 타입을 제외하고 가장 많이 마주치는 타입은 *객체 타입*입니다. 객체는 프로퍼티를 가지는 JavaScript 값을 말하는데, 대부분의 경우가 이에 해당하죠! 객체 타입을 정의하려면, 해당 객체의 프로퍼티들과 각 프로퍼티의 타입들을 나열하기만 하면 됩니다. @@ -188,7 +188,7 @@ printCoord({ x: 3, y: 7 }); ### 옵셔널 프로퍼티 -객체 타입은 일부 또는 모든 프로퍼티의 타입을 선택적인 타입, 즉 _옵셔널_로 지정할 수 있습니다. +객체 타입은 일부 또는 모든 프로퍼티의 타입을 선택적인 타입, 즉 *옵셔널*로 지정할 수 있습니다. 프로퍼티 이름 뒤에 `?`를 붙이면 됩니다. ```ts twoslash @@ -201,7 +201,7 @@ printName({ first: "Alice", last: "Alisson" }); ``` JavaScript에서는 존재하지 않는 프로퍼티에 접근하였을 때, 런타임 오류가 발생하지 않고 `undefined` 값을 얻게 됩니다. -이 때문에 옵셔널 프로퍼티를 _읽었을_ 때, 해당 값을 사용하기에 앞서 `undefined`인지 여부를 확인해야 합니다. +이 때문에 옵셔널 프로퍼티를 *읽었을* 때, 해당 값을 사용하기에 앞서 `undefined`인지 여부를 확인해야 합니다. ```ts twoslash // @errors: 2532 @@ -221,13 +221,13 @@ function printName(obj: { first: string; last?: string }) { ## 유니언 타입 TypeScript의 타입 시스템에서는 기존의 타입을 기반으로 다양한 연산자를 사용하여 새로운 타입을 만들 수 있습니다. -몇몇 타입들을 사용하는 법을 알았으니, 이제 이 타입들을 _조합하여_ 흥미로운 방식으로 사용해볼 시간입니다. +몇몇 타입들을 사용하는 법을 알았으니, 이제 이 타입들을 *조합하여* 흥미로운 방식으로 사용해볼 시간입니다. ### 유니언 타입 정의하기 -타입을 조합하는 첫 번째 방법은 _유니언_ 타입을 사용하는 것입니다. -유니언 타입은 서로 다른 두 개 이상의 타입들을 사용하여 만드는 것으로, 유니언 타입의 값은 타입 조합에 사용된 타입 중 _무엇이든 하나_를 타입으로 가질 수 있습니다. -조합에 사용된 각 타입을 유니언 타입의 _멤버_라고 부릅니다. +타입을 조합하는 첫 번째 방법은 *유니언* 타입을 사용하는 것입니다. +유니언 타입은 서로 다른 두 개 이상의 타입들을 사용하여 만드는 것으로, 유니언 타입의 값은 타입 조합에 사용된 타입 중 *무엇이든 하나*를 타입으로 가질 수 있습니다. +조합에 사용된 각 타입을 유니언 타입의 *멤버*라고 부릅니다. 문자열 또는 숫자를 받을 수 있는 함수를 작성해보겠습니다. @@ -246,10 +246,10 @@ printId({ myID: 22342 }); ### 유니언 타입 사용하기 -유니언 타입에 맞는 값을 _제공하는_ 것은 간단합니다. 유니언 타입의 멤버 중 하나에 해당하는 타입을 제공하면 됩니다. -유니언 타입인 값이 코드상에 _존재할 때_, 이를 어떻게 사용해야 할까요? +유니언 타입에 맞는 값을 *제공하는* 것은 간단합니다. 유니언 타입의 멤버 중 하나에 해당하는 타입을 제공하면 됩니다. +유니언 타입인 값이 코드상에 *존재할 때*, 이를 어떻게 사용해야 할까요? -TypeScript에서 유니언을 다룰 때는 해당 유니언 타입의 _모든_ 멤버에 대하여 유효한 작업일 때에만 허용됩니다. +TypeScript에서 유니언을 다룰 때는 해당 유니언 타입의 *모든* 멤버에 대하여 유효한 작업일 때에만 허용됩니다. 예를 들어 `string | number`라는 유니언 타입의 경우, `string` 타입에만 유효한 메서드는 사용할 수 없습니다. ```ts twoslash @@ -259,8 +259,8 @@ function printId(id: number | string) { } ``` -이를 해결하려면 코드상에서 유니언을 _좁혀야_ 하는데, 이는 타입 표기가 없는 JavaScript에서 벌어지는 일과 동일합니다. -_좁히기_란 TypeScript가 코드 구조를 바탕으로 어떤 값을 보다 구체적인 타입으로 추론할 수 있을 때 발생합니다. +이를 해결하려면 코드상에서 유니언을 *좁혀야* 하는데, 이는 타입 표기가 없는 JavaScript에서 벌어지는 일과 동일합니다. +*좁히기*란 TypeScript가 코드 구조를 바탕으로 어떤 값을 보다 구체적인 타입으로 추론할 수 있을 때 발생합니다. 예를 들어, TypeScript는 오직 `string` 값만이 `typeof` 연산의 결괏값으로 `"string"`을 가질 수 있다는 것을 알고 있습니다. @@ -304,18 +304,18 @@ function getFirstThree(x: number[] | string) { } ``` -> 유니언은 의미상 _합집합_을 뜻하는데, 실제로는 유니언 타입이 프로퍼티들의 _교집합_을 가리키는 것처럼 보여 헷갈리게 느낄 수 있습니다. -> 이는 지극히 우연이 아닙니다. _유니언_이라는 명칭은 타입 이론에서 비롯된 것입니다. -> `number | string` _유니언_ 타입은 각각의 타입을 가지는 _값들에 대하여_ 합집합을 취하여 구성됩니다. -> 두 집합과 각각의 집합에 대한 특성이 주어졌을 때, 두 집합의 _유니언_에는 각각의 특성들의 _교집합_만이 적용된다는 점에 유의하시기 바랍니다. -> 예를 들어, 한 방에는 모자를 쓰고 키가 큰 사람들이 있고 다른 방에는 모자를 쓰고 스페인어를 사용하는 사람들이 있다고 합시다. 이때 두 방을 합친다면, _모든_ 사람들에 대하여 우리가 알 수 있는 사실은 바로 누구나 반드시 모자를 쓰고 있다는 것입니다. +> 유니언은 의미상 *합집합*을 뜻하는데, 실제로는 유니언 타입이 프로퍼티들의 *교집합*을 가리키는 것처럼 보여 헷갈리게 느낄 수 있습니다. +> 이는 지극히 우연이 아닙니다. *유니언*이라는 명칭은 타입 이론에서 비롯된 것입니다. +> `number | string` *유니언* 타입은 각각의 타입을 가지는 *값들에 대하여* 합집합을 취하여 구성됩니다. +> 두 집합과 각각의 집합에 대한 특성이 주어졌을 때, 두 집합의 *유니언*에는 각각의 특성들의 *교집합*만이 적용된다는 점에 유의하시기 바랍니다. +> 예를 들어, 한 방에는 모자를 쓰고 키가 큰 사람들이 있고 다른 방에는 모자를 쓰고 스페인어를 사용하는 사람들이 있다고 합시다. 이때 두 방을 합친다면, *모든* 사람들에 대하여 우리가 알 수 있는 사실은 바로 누구나 반드시 모자를 쓰고 있다는 것입니다. ## 타입 별칭 지금까지는 객체 타입과 유니언 타입을 사용할 때 직접 해당 타입을 표기하였습니다. 이는 편리하지만, 똑같은 타입을 한 번 이상 재사용하거나 또 다른 이름으로 부르고 싶은 경우도 존재합니다. -_타입 별칭_은 바로 이런 경우를 위하여 존재하며, _타입_을 위한 _이름_을 제공합니다. +*타입 별칭*은 바로 이런 경우를 위하여 존재하며, *타입*을 위한 *이름*을 제공합니다. 타입 별칭의 구문은 아래와 같습니다. ```ts twoslash @@ -334,20 +334,20 @@ printCoord({ x: 100, y: 100 }); ``` 타입 별칭을 사용하면 단지 객체 타입뿐이 아닌 모든 타입에 대하여 새로운 이름을 부여할 수 있습니다. -예를 들어, 아래와 같이 유니언 타입에 대하여 타입 별칭을 부여할 수도 있습니다. +예를 들어, 아래와 같이 유니언 타입에 대하여 타입 별칭을 부여할 수도 있습니다. ```ts twoslash type ID = number | string; ``` -타입 별칭은 _단지_ 별칭에 지나지 않는다는 점에 유의하시기 바랍니다. 즉, 타입 별칭을 사용하여도 동일 타입에 대하여 각기 구별되는 "여러 버전"을 만드는 것은 아닙니다. +타입 별칭은 *단지* 별칭에 지나지 않는다는 점에 유의하시기 바랍니다. 즉, 타입 별칭을 사용하여도 동일 타입에 대하여 각기 구별되는 "여러 버전"을 만드는 것은 아닙니다. 별칭을 사용하는 것은, 별도로 이름 붙인 타입을 새로 작성하는 것입니다. -다시 말해, 아래 코드는 틀린 것처럼 _보일 수_ 있지만, TypeScript에서는 이것이 정상인데 그 이유는 각각의 타입들이 동일 타입에 대한 별칭들이기 때문입니다. +다시 말해, 아래 코드는 틀린 것처럼 *보일 수* 있지만, TypeScript에서는 이것이 정상인데 그 이유는 각각의 타입들이 동일 타입에 대한 별칭들이기 때문입니다. ```ts twoslash declare function getInput(): string; declare function sanitize(str: string): string; -// ---중간 생략--- +// ---cut--- type UserInputSanitizedString = string; function sanitizeInput(str: string): UserInputSanitizedString { @@ -363,7 +363,7 @@ userInput = "new input"; ## 인터페이스 -_인터페이스 선언_은 객체 타입을 만드는 또 다른 방법입니다. +*인터페이스 선언*은 객체 타입을 만드는 또 다른 방법입니다. ```ts twoslash interface Point { @@ -380,8 +380,8 @@ printCoord({ x: 100, y: 100 }); ``` 타입 별칭을 사용한 경우와 마찬가지로, 위 예시 코드는 마치 타입이 없는 임의의 익명 객체를 사용하는 것처럼 동작합니다. -TypeScript는 오직 `printCoord`에 전달된 값의 _구조_에만 관심을 가집니다. 즉, 예측된 프로퍼티를 가졌는지 여부만을 따집니다. -이처럼, 타입이 가지는 구조와 능력에만 관심을 가진다는 점은 TypeScript가 _구조적_ 타입 시스템이라고 불리는 이유입니다. +TypeScript는 오직 `printCoord`에 전달된 값의 *구조*에만 관심을 가집니다. 즉, 예측된 프로퍼티를 가졌는지 여부만을 따집니다. +이처럼, 타입이 가지는 구조와 능력에만 관심을 가진다는 점은 TypeScript가 *구조적* 타입 시스템이라고 불리는 이유입니다. ### 타입 별칭과 인터페이스의 차이점 @@ -404,7 +404,7 @@ interface Animal { interface Bear extends Animal { honey: boolean }
-const bear = getBear() +const bear = getBear() bear.name bear.honey @@ -415,8 +415,8 @@ bear.honey type Animal = { name: string }
-type Bear = Animal & { - honey: Boolean +type Bear = Animal & { + honey: Boolean }
const bear = getBear(); bear.name; @@ -459,7 +459,7 @@ type Window = { - TypeScript 4.2 이전 버전에서는, 타입 별칭 이름이 오류 메시지에 [나타날 수 있고](/play?#code/PTAEGEHsFsAcEsA2BTATqNrLusgzngIYDm+oA7koqIYuYQJ56gCueyoAUCKAC4AWHAHaFcoSADMaQ0PCG80EwgGNkALk6c5C1EtWgAsqOi1QAb06groEbjWg8vVHOKcAvpokshy3vEgyyMr8kEbQJogAFND2YREAlOaW1soBeJAoAHSIkMTRmbbI8e6aPMiZxJmgACqCGKhY6ABGyDnkFFQ0dIzMbBwCwqIccabcYLyQoKjIEmh8kwN8DLAc5PzwwbLMyAAeK77IACYaQSEjUWZWhfYAjABMAMwALA+gbsVjoADqgjKESytQPxCHghAByXigYgBfr8LAsYj8aQMUASbDQcRSExCeCwFiIQh+AKfAYyBiQFgOPyIaikSGLQo0Zj-aazaY+dSaXjLDgAGXgAC9CKhDqAALxJaw2Ib2RzOISuDycLw+ImBYKQflCkWRRD2LXCw6JCxS1JCdJZHJ5RAFIbFJU8ADKC3WzEcnVZaGYE1ABpFnFOmsFhsil2uoHuzwArO9SmAAEIsSFrZB-GgAjjA5gtVN8VCEc1o1C4Q4AGlR2AwO1EsBQoAAbvB-gJ4HhPgB5aDwem-Ph1TCV3AEEirTp4ELtRbTPD4vwKjOfAuioSQHuDXBcnmgACC+eCONFEs73YAPGGZVT5cRyyhiHh7AAON7lsG3vBggB8XGV3l8-nVISOgghxoLq9i7io-AHsayRWGaFrlFauq2rg9qaIGQHwCBqChtKdgRo8TxRjeyB3o+7xAA), 때로는 동등한 익명 타입을 대신하여 나타날 수 있습니다(이는 경우에 따라 바람직할 수도 있고 아닐 수도 있습니다). 인터페이스는 항상 오류 메시지에 이름이 나타납니다. - 타입 별칭은 [선언 병합에 포함될 수 없지만, 인터페이스는 포함될 수 있습니다](/play?#code/PTAEEEDtQS0gXApgJwGYEMDGjSfdAIx2UQFoB7AB0UkQBMAoEUfO0Wgd1ADd0AbAK6IAzizp16ALgYM4SNFhwBZdAFtV-UAG8GoPaADmNAcMmhh8ZHAMMAvjLkoM2UCvWad+0ARL0A-GYWVpA29gyY5JAWLJAwGnxmbvGgALzauvpGkCZmAEQAjABMAMwALLkANBl6zABi6DB8okR4Jjg+iPSgABboovDk3jjo5pbW1d6+dGb5djLwAJ7UoABKiJTwjThpnpnGpqPBoTLMAJrkArj4kOTwYmycPOhW6AR8IrDQ8N04wmo4HHQCwYi2Waw2W1S6S8HX8gTGITsQA). - 인터페이스는 [오직 객체의 모양을 선언하는 데에만 사용되며, 기존의 원시 타입에 별칭을 부여하는 데에는 사용할 수는 없습니다](/play?#code/PTAEAkFMCdIcgM6gC4HcD2pIA8CGBbABwBtIl0AzUAKBFAFcEBLAOwHMUBPQs0XFgCahWyGBVwBjMrTDJMAshOhMARpD4tQ6FQCtIE5DWoixk9QEEWAeV37kARlABvaqDegAbrmL1IALlAEZGV2agBfampkbgtrWwMAJlAAXmdXdy8ff0Dg1jZwyLoAVWZ2Lh5QVHUJflAlSFxROsY5fFAWAmk6CnRoLGwmILzQQmV8JmQmDzI-SOiKgGV+CaYAL0gBBdyy1KCQ-Pn1AFFplgA5enw1PtSWS+vCsAAVAAtB4QQWOEMKBuYVUiVCYvYQsUTQcRSBDGMGmKSgAAa-VEgiQe2GLgKQA). -- 인터페이스의 이름은 [항상 있는 그대로](/play?#code/PTAEGEHsFsAcEsA2BTATqNrLusgzngIYDm+oA7koqIYuYQJ56gCueyoAUCKAC4AWHAHaFcoSADMaQ0PCG80EwgGNkALk6c5C1EtWgAsqOi1QAb06groEbjWg8vVHOKcAvpokshy3vEgyyMr8kEbQJogAFND2YREAlOaW1soBeJAoAHSIkMTRmbbI8e6aPMiZxJmgACqCGKhY6ABGyDnkFFQ0dIzMbBwCwqIccabcYLyQoKjIEmh8kwN8DLAc5PzwwbLMyAAeK77IACYaQSEjUWY2Q-YAjABMAMwALA+gbsVjNXW8yxySoAADaAA0CCaZbPh1XYqXgOIY0ZgmcK0AA0nyaLFhhGY8F4AHJmEJILCWsgZId4NNfIgGFdcIcUTVfgBlZTOWC8T7kAJ42G4eT+GS42QyRaYbCgXAEEguTzeXyCjDBSAAQSE8Ai0Xsl0K9kcziExDeiQs1lAqSE6SyOTy0AKQ2KHk4p1V6s1OuuoHuzwArMagA) 오류 메시지에 나타납니다. 단, 이는 _오직_ 코드상에서 해당 인터페이스가 이름으로 사용되었을 때에만 해당합니다. +- 인터페이스의 이름은 [항상 있는 그대로](/play?#code/PTAEGEHsFsAcEsA2BTATqNrLusgzngIYDm+oA7koqIYuYQJ56gCueyoAUCKAC4AWHAHaFcoSADMaQ0PCG80EwgGNkALk6c5C1EtWgAsqOi1QAb06groEbjWg8vVHOKcAvpokshy3vEgyyMr8kEbQJogAFND2YREAlOaW1soBeJAoAHSIkMTRmbbI8e6aPMiZxJmgACqCGKhY6ABGyDnkFFQ0dIzMbBwCwqIccabcYLyQoKjIEmh8kwN8DLAc5PzwwbLMyAAeK77IACYaQSEjUWY2Q-YAjABMAMwALA+gbsVjNXW8yxySoAADaAA0CCaZbPh1XYqXgOIY0ZgmcK0AA0nyaLFhhGY8F4AHJmEJILCWsgZId4NNfIgGFdcIcUTVfgBlZTOWC8T7kAJ42G4eT+GS42QyRaYbCgXAEEguTzeXyCjDBSAAQSE8Ai0Xsl0K9kcziExDeiQs1lAqSE6SyOTy0AKQ2KHk4p1V6s1OuuoHuzwArMagA) 오류 메시지에 나타납니다. 단, 이는 *오직* 코드상에서 해당 인터페이스가 이름으로 사용되었을 때에만 해당합니다. 대부분의 경우 개인적 선호에 따라 인터페이스와 타입 중에서 선택할 수 있으며, 필요하다면 TypeScript가 다른 선택을 제안할 것입니다. 잘 모르겠다면, 우선 `interface`를 사용하고 이후 문제가 발생하였을 때 `type`을 사용하기 바랍니다. @@ -467,9 +467,9 @@ type Window = { 때로는 TypeScript보다 당신이 어떤 값의 타입에 대한 정보를 더 잘 아는 경우도 존재합니다. -예를 들어 코드상에서 `document.getElementById`가 사용되는 경우, TypeScript는 이때 `HTMLElement` 중에 _무언가_가 반환된다는 것만을 알 수 있는 반면에, 당신은 페이지 상에서 사용되는 ID로는 언제나 `HTMLCanvasElement`가 반환된다는 사실을 이미 알고 있을 수도 있습니다. +예를 들어 코드상에서 `document.getElementById`가 사용되는 경우, TypeScript는 이때 `HTMLElement` 중에 *무언가*가 반환된다는 것만을 알 수 있는 반면에, 당신은 페이지 상에서 사용되는 ID로는 언제나 `HTMLCanvasElement`가 반환된다는 사실을 이미 알고 있을 수도 있습니다. -이런 경우, _타입 단언_을 사용하면 타입을 좀 더 구체적으로 명시할 수 있습니다. +이런 경우, *타입 단언*을 사용하면 타입을 좀 더 구체적으로 명시할 수 있습니다. ```ts twoslash const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement; @@ -486,7 +486,7 @@ const myCanvas = document.getElementById("main_canvas"); > 기억하세요: 타입 단언은 컴파일 시간에 제거되므로, 타입 단언에 관련된 검사는 런타임 중에 이루어지지 않습니다. > 타입 단언이 틀렸더라도 예외가 발생하거나 `null`이 생성되지 않을 것입니다. -TypeScript에서는 _보다 구체적인_ 또는 _덜 구체적인_ 버전의 타입으로 변환하는 타입 단언만이 허용됩니다. +TypeScript에서는 *보다 구체적인* 또는 *덜 구체적인* 버전의 타입으로 변환하는 타입 단언만이 허용됩니다. 이러한 규칙은 아래와 같은 "불가능한" 강제 변환을 방지합니다. ```ts twoslash @@ -500,13 +500,13 @@ const x = "hello" as number; ```ts twoslash declare const expr: any; type T = { a: 1; b: 2; c: 3 }; -// ---중간 생략--- +// ---cut--- const a = (expr as any) as T; ``` ## 리터럴 타입 -`string`과 `number`와 같은 일반적인 타입 이외에도, _구체적인_ 문자열과 숫자 값을 타입 위치에서 지정할 수 있습니다. +`string`과 `number`와 같은 일반적인 타입 이외에도, *구체적인* 문자열과 숫자 값을 타입 위치에서 지정할 수 있습니다. 이를 이해하려면, JavaScript에서 변수 선언에 제공되는 다양한 방법들을 떠올려보시기 바랍니다. `var`와 `let` 모두 변수에 저장 가능한 값의 종류를 변경할 수 있으며, `const`는 이것이 불가능합니다. 이러한 특징들은 TypeScript가 리터럴 값을 위한 타입을 생성하는 방식에 그대로 반영됩니다. @@ -538,7 +538,7 @@ x = "howdy"; 단 하나의 값만을 가질 수 있는 변수는 그다지 쓸모가 없죠! -하지만 리터럴을 유니언과 _함께 사용하면_, 보다 유용한 개념들을 표현할 수 있게 됩니다. 예를 들어, 특정 종류의 값들만을 인자로 받을 수 있는 함수를 정의하는 경우가 있습니다. +하지만 리터럴을 유니언과 *함께 사용하면*, 보다 유용한 개념들을 표현할 수 있게 됩니다. 예를 들어, 특정 종류의 값들만을 인자로 받을 수 있는 함수를 정의하는 경우가 있습니다. ```ts twoslash // @errors: 2345 @@ -583,7 +583,7 @@ configure("automatic"); ```ts twoslash declare const someCondition: boolean; -// ---중간 생략--- +// ---cut--- const obj = { counter: 0 }; if (someCondition) { obj.counter = 1; @@ -591,7 +591,7 @@ if (someCondition) { ``` 기존에 값이 `0`이었던 필드에 `1`을 대입하였을 때 TypeScript는 이를 오류로 간주하지 않습니다. -이를 달리 말하면 `obj.counter`는 반드시 `number` 타입을 가져야 하며, `0` 리터럴 타입을 가질 수 없다는 의미입니다. 왜냐하면 타입은 _읽기_ 및 _쓰기_ 두 동작을 결정하는 데에 사용되기 때문입니다. +이를 달리 말하면 `obj.counter`는 반드시 `number` 타입을 가져야 하며, `0` 리터럴 타입을 가질 수 없다는 의미입니다. 왜냐하면 타입은 *읽기* 및 *쓰기* 두 동작을 결정하는 데에 사용되기 때문입니다. 동일한 사항이 문자열에도 적용됩니다. @@ -618,14 +618,14 @@ handleRequest(req.url, req.method); handleRequest(req.url, req.method as "GET"); ``` - 수정 1은 "`req.method`가 항상 _리터럴 타입_ `"GET"`이기를 의도하며, 이에 따라 해당 필드에 `"GUESS"`와 같은 값이 대입되는 경우를 미연에 방지하겠다"는 것을 의미합니다. + 수정 1은 `req.method`가 항상 *리터럴 타입* `"GET"`이기를 의도하며, 이에 따라 해당 필드에 `"GUESS"`와 같은 값이 대입되는 경우를 미연에 방지하겠다"는 것을 의미합니다. 수정 2는 "무슨 이유인지, `req.method`가 `"GET"`을 값으로 가진다는 사실을 알고 있다"는 것을 의미합니다. 2. `as const`를 사용하여 객체 전체를 리터럴 타입으로 변환할 수 있습니다. ```ts twoslash declare function handleRequest(url: string, method: "GET" | "POST"): void; - // ---중간 생략--- + // ---cut--- const req = { url: "https://example.com", method: "GET" } as const; handleRequest(req.url, req.method); ``` @@ -636,18 +636,18 @@ handleRequest(req.url, req.method); JavaScript에는 빈 값 또는 초기화되지 않은 값을 가리키는 두 가지 원시값이 존재합니다. 바로 `null`과 `undefined`입니다. -TypeScript에는 각 값에 대응하는 동일한 이름의 두 가지 _타입_이 존재합니다. 각 타입의 동작 방식은 `strictNullChecks` 옵션의 설정 여부에 따라 달라집니다. +TypeScript에는 각 값에 대응하는 동일한 이름의 두 가지 *타입*이 존재합니다. 각 타입의 동작 방식은 `strictNullChecks` 옵션의 설정 여부에 따라 달라집니다. ### `strictNullChecks`가 설정되지 않았을 때 -`strictNullChecks`가 _설정되지 않았다면_, 어떤 값이 `null` 또는 `undefined`일 수 있더라도 해당 값에 평소와 같이 접근할 수 있으며, `null`과 `undefined`는 모든 타입의 변수에 대입될 수 있습니다. +`strictNullChecks`가 *설정되지 않았다면*, 어떤 값이 `null` 또는 `undefined`일 수 있더라도 해당 값에 평소와 같이 접근할 수 있으며, `null`과 `undefined`는 모든 타입의 변수에 대입될 수 있습니다. 이는 Null 검사를 하지 않는 언어(C#, Java 등)의 동작 방식과 유사합니다. Null 검사의 부재는 버그의 주요 원인이 되기도 합니다. 별다른 이유가 없다면, 코드 전반에 걸쳐 `strictNullChecks` 옵션을 설정하는 것을 항상 권장합니다. ### `strictNullChecks` 설정되었을 때 -`strictNullChecks`가 _설정되었다면_, 어떤 값이 `null` 또는 `undefined`일 때, 해당 값과 함께 메서드 또는 프로퍼티를 사용하기에 앞서 해당 값을 테스트해야 합니다. -옵셔널 프로퍼티를 사용하기에 앞서 `undefined` 여부를 검사하는 것과 마찬가지로, _좁히기_를 통하여 `null`일 수 있는 값에 대한 검사를 수행할 수 있습니다. +`strictNullChecks`가 *설정되었다면*, 어떤 값이 `null` 또는 `undefined`일 때, 해당 값과 함께 메서드 또는 프로퍼티를 사용하기에 앞서 해당 값을 테스트해야 합니다. +옵셔널 프로퍼티를 사용하기에 앞서 `undefined` 여부를 검사하는 것과 마찬가지로, *좁히기*를 통하여 `null`일 수 있는 값에 대한 검사를 수행할 수 있습니다. ```ts twoslash function doSomething(x: string | undefined) { @@ -672,18 +672,18 @@ function liveDangerously(x?: number | undefined) { } ``` -다른 타입 단언과 마찬가지로 이 구문은 코드의 런타임 동작을 변화시키지 않으므로, `!` 연산자는 반드시 해당 값이 `null` 또는 `undefined`가 _아닌_ 경우에만 사용해야 합니다. +다른 타입 단언과 마찬가지로 이 구문은 코드의 런타임 동작을 변화시키지 않으므로, `!` 연산자는 반드시 해당 값이 `null` 또는 `undefined`가 *아닌* 경우에만 사용해야 합니다. -### 열거형 +## 열거형 -열거형은 TypeScript가 JavaScript에 추가하는 기능으로, 어떤 값이 _이름이 있는 상수 집합_에 속한 값 중 하나일 수 있도록 제한하는 기능입니다. 대부분의 TypeScript 기능과 달리, 이 기능은 JavaScript에 타입 수준이 _아닌_, 언어와 런타임 수준에 추가되는 기능입니다. 따라서 열거형이 무엇인지는 알 필요가 있겠으나, 그 사용법을 명확하게 파악하지 않았다면 실제 사용은 보류하는 것이 좋습니다. 열거형에 대한 자세한 내용을 확인하려면 [열거형 문서](https://www.typescriptlang.org/ko/docs/handbook/enums.html)를 읽어보시기 바랍니다. +열거형은 TypeScript가 JavaScript에 추가하는 기능으로, 어떤 값이 *이름이 있는 상수 집합*에 속한 값 중 하나일 수 있도록 제한하는 기능입니다. 대부분의 TypeScript 기능과 달리, 이 기능은 JavaScript에 타입 수준이 *아닌*, 언어와 런타임 수준에 추가되는 기능입니다. 따라서 열거형이 무엇인지는 알 필요가 있겠으나, 그 사용법을 명확하게 파악하지 않았다면 실제 사용은 보류하는 것이 좋습니다. 열거형에 대한 자세한 내용을 확인하려면 [열거형 문서](https://www.typescriptlang.org/ko/docs/handbook/enums.html)를 읽어보시기 바랍니다. -### 자주 사용되지 않는 원시형 타입 +## 자주 사용되지 않는 원시형 타입 앞서 언급한 타입 이외에, 타입 시스템에 존재하는 나머지 JavaScript 원시 타입들을 다루도록 하겠습니다. 물론, 여기서 깊게 다루지는 않을 것입니다. -##### `bigint` +#### `bigint` ES2020 이후, 아주 큰 정수를 다루기 위한 원시 타입이 JavaScript에 추가되었습니다. 바로 `bigint`입니다. @@ -699,7 +699,7 @@ const anotherHundred: bigint = 100n; BigInt에 대한 더 자세한 내용은 [TypeScript 3.2 릴리즈 노트]((/docs/handbook/release-notes/typescript-3-2.html#bigint))에서 확인할 수 있습니다. -##### `symbol` +#### `symbol` `symbol`은 전역적으로 고유한 참조값을 생성하는 데에 사용할 수 있는 원시 타입이며, `Symbol()` 함수를 통하여 생성할 수 있습니다. diff --git a/docs/documentation/ko/handbook-v2/Type Manipulation/Conditional Types.md b/docs/documentation/ko/handbook-v2/Type Manipulation/Conditional Types.md new file mode 100644 index 00000000..49192e56 --- /dev/null +++ b/docs/documentation/ko/handbook-v2/Type Manipulation/Conditional Types.md @@ -0,0 +1,270 @@ +--- +title: Conditional Types +layout: docs +permalink: /ko/docs/handbook/2/conditional-types.html +oneline: "타입 시스템에서 if문 처럼 동작하는 타입 생성하기." +--- + +대부분 유용한 프로그램의 핵심은, 입력에 따라 출력이 결정되어야 한다는 것입니다. +JavaScript 프로그램도 크게 다르진 않지만, 값의 타입을 쉽게 검사할 수 있다는 사실을 고려할 때, 출력에 대한 결정은 또한 입력의 타입에도 기반합니다. +*조건부 타입* 은 입력과 출력 타입간의 관계를 설명하는 데 도움을 줄 수 있습니다. + +```ts twoslash +interface Animal { + live(): void; +} +interface Dog extends Animal { + woof(): void; +} + +type Example1 = Dog extends Animal ? number : string; +// ^? + +type Example2 = RegExp extends Animal ? number : string; +// ^? +``` + +조건부 타입은 JavaScript에 있는 삼항 연산자 조건문 (`condition ? trueExpression : falseExpression`) 같은 형태를 가집니다. + +```ts twoslash +type SomeType = any; +type OtherType = any; +type TrueType = any; +type FalseType = any; +type Stuff = + // ---cut--- + SomeType extends OtherType ? TrueType : FalseType; +``` + +`extends`를 기준으로 왼쪽에 있는 타입이 오른쪽 타입에 할당할 수 있다면 첫 번째 분기("참"값 분기)를, 그렇지 않다면 뒤의 분기("거짓"값 분기)를 얻게 됩니다. + +`Dog extends Animal` 에 따라 `number`나 `string`인지 알려주는 것 말곤, 위의 예제에서 조건부 타입은 그다지 유용해 보이지 않습니다! +하지만 제네릭과 함께 사용될 때 조건부 타입은 강력한 힘을 갖습니다. + +예를 들어, 다음 `createLabel` 함수를 살펴보겠습니다. + +```ts twoslash +interface IdLabel { + id: number /* some fields */; +} +interface NameLabel { + name: string /* other fields */; +} + +function createLabel(id: number): IdLabel; +function createLabel(name: string): NameLabel; +function createLabel(nameOrId: string | number): IdLabel | NameLabel; +function createLabel(nameOrId: string | number): IdLabel | NameLabel { + throw "unimplemented"; +} +``` + +createLabel의 오버로드들은 입력 타입에 따른 단일 JavaScript 함수를 나타냅니다. 다음을 주목하세요. + +1. 만약 라이브러리가 매번 API 전체에서 비슷한 종류의 함수를 만들어야 한다면 번거로워집니다. +2. 우린 3가지 오버로드 즉, 각 케이스별로 *확실한* 타입을 가지거나 (각각 `number`와 `string`) 그리고 일반적인 케이스(`string | number`) 가져야 합니다. `createLabel`의 새로운 타입을 다루기 위해선 오버로드의 수는 기하급수적으로 증가합니다. + +대신에 조건부 타입으로 로직을 인코딩할 수 있습니다. + +```ts twoslash +interface IdLabel { + id: number /* some fields */; +} +interface NameLabel { + name: string /* other fields */; +} +// ---cut--- +type NameOrId = T extends number + ? IdLabel + : NameLabel; +``` + +조건부 타입을 사용하면 단일 함수까지 오버로드 없이 단순화 시킬 수 있습니다. + +```ts twoslash +interface IdLabel { + id: number /* some fields */; +} +interface NameLabel { + name: string /* other fields */; +} +type NameOrId = T extends number + ? IdLabel + : NameLabel; +// ---cut--- +function createLabel(idOrName: T): NameOrId { + throw "unimplemented"; +} + +let a = createLabel("typescript"); +// ^? + +let b = createLabel(2.8); +// ^? + +let c = createLabel(Math.random() ? "hello" : 42); +// ^? +``` + +### 조건부 타입으로 제한하기 + +종종, 조건부 타입의 검사에서 새로운 정보를 얻을 수 있습니다. +타입 가드가 더 구체적인 타입으로 좁혀주듯이, 조건부 타입의 "참"값 분기는 대조하는 타입에 따라서 제네릭을 더 제한할 수 있습니다. + +다음 예를 살펴보겠습니다. + +```ts twoslash +// @errors: 2536 +type MessageOf = T["message"]; +``` + +위 예제에서, `T`가 `message` 프로퍼티를 가지고 있는지 알 수 없기 때문에 TypeScript에서 오류가 발생합니다. +`T`의 타입을 제한해서 TypeScript가 더이상 오류를 내지 않도록 만들 수 있습니다. + +```ts twoslash +type MessageOf = T["message"]; + +interface Email { + message: string; +} + +type EmailMessageContents = MessageOf; +// ^? +``` + +하지만 `MessageOf` 가 아무 타입이나 받을 수 있고, `message` 프로퍼티가 없으면 `never` 타입으로 결정하도록 만들 수 있을까요? +여기서 제약 조건을 외부로 옮기고, 조건부 타입을 적용하면 가능합니다. + +```ts twoslash +type MessageOf = T extends { message: unknown } ? T["message"] : never; + +interface Email { + message: string; +} + +interface Dog { + bark(): void; +} + +type EmailMessageContents = MessageOf; +// ^? + +type DogMessageContents = MessageOf; +// ^? +``` + +"참"값 분기내에서는 TypeScript는 `T`가 `message` 프로퍼티를 가지고 *있을 것을* 알 수 있습니다. + +또 다른 예제에서 배열 타입이면 배열의 개별 요소 타입으로 평탄화 시키지만, 배열 타입이 아니면 그대로 유지하는 `Flatten` 타입을 만들 수 있습니다. + +```ts twoslash +type Flatten = T extends any[] ? T[number] : T; + +// Extracts out the element type. +type Str = Flatten; +// ^? + +// Leaves the type alone. +type Num = Flatten; +// ^? +``` + +`Flatten`에 배열 타입이 주어지면, `number`를 사용한 인덱스 접근을 통해 `string[]`의 요소 타입을 가져올 수 있습니다. +그렇지 않으면, 주어진 타입을 반환합니다. + +### 조건부 타입 내에서 추론하기 + +위에서 제약 조건을 가진 조건부 타입을 이용해서 타입을 추출할 수 있다는 점을 살펴봤습니다. +이 부분은 조건부 타입을 더 쉽게 만드는 평범한 작업이 됩니다. + +조건부 타입은 `infer` 키워드를 사용해서 "참"값 분기에서 비교하는 타입을 추론할 수 있습니다. +예를 들어, `Flatten`에서 인덱싱된 접근 타입으로 "직접" 추출하지 않고 요소 타입을 추론할 수 있습니다. + +```ts twoslash +type Flatten = Type extends Array ? Item : Type; +``` + +여기 "참"값 분기에서 `T`의 요소 타입을 어떻게 제시할 필요 없이, `infer` 키워드를 새 제네릭 타입 변수 `Item`에 선언적으로 사용했습니다. +이 방식은 관심 있는 타입의 구조를 깊게 분석하지 않아도 되도록 만들어줍니다. + +`infer` 키워드를 사용해서 유용한 헬퍼 타입 별칭을 사용할 수 있습니다. +예를 들어 함수 타입에서 리턴 타입을 추출하는 간단한 케이스를 살펴보겠습니다. + +```ts twoslash +type GetReturnType = Type extends (...args: never[]) => infer Return + ? Return + : never; + +type Num = GetReturnType<() => number>; +// ^? + +type Str = GetReturnType<(x: string) => string>; +// ^? + +type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]>; +// ^? +``` + +여러 호출 시그니처 (오버로트 함수 타입 같이)를 가진 타입을 추론할 때, *마지막* 시그니처 (아마, 모든 케이스에 허용되는)로 추론하게 됩니다. 인자 타입의 목록에 기반해서 오버로드들을 처리할 수는 없습니다. + +```ts twoslash +declare function stringOrNum(x: string): number; +declare function stringOrNum(x: number): string; +declare function stringOrNum(x: string | number): string | number; + +type T1 = ReturnType; +// ^? +``` + +## 분산적인 조건부 타입 + +제네릭 타입 위에서 조건부 타입은 유니언 타입을 만나면 *분산적으로* 동작합니다. +예를 들어 다음을 보겠습니다. + +```ts twoslash +type ToArray = Type extends any ? Type[] : never; +``` + +`ToArray`에 유니언 타입을 넘기면 조건부 타입은 유니언의 각 멤버에 적용됩니다. + +```ts twoslash +type ToArray = Type extends any ? Type[] : never; + +type StrArrOrNumArr = ToArray; +// ^? +``` + +`StrArrOrNumArr`이 동작하는 방식은 다음과 같습니다. + +```ts twoslash +type StrArrOrNumArr = + // ---cut--- + string | number; +``` + +유니언의 각 멤버 타입은 효율적으로 매핑됩니다. + +```ts twoslash +type ToArray = Type extends any ? Type[] : never; +type StrArrOrNumArr = + // ---cut--- + ToArray | ToArray; +``` + +그리고 다음과 같이 결과가 나옵니다. + +```ts twoslash +type StrArrOrNumArr = + // ---cut--- + string[] | number[]; +``` + +일반적으로 분산성이 원하는 동작입니다. 이러한 동작을 방지하려면 `extends`키워드의 양 옆을 대괄호로 감싸면 됩니다. + +```ts twoslash +type ToArrayNonDist = [Type] extends [any] ? Type[] : never; + +// 'StrArrOrNumArr' is no longer a union. +type StrArrOrNumArr = ToArrayNonDist; +// ^? +``` diff --git a/docs/documentation/ko/handbook-v2/Type Manipulation/Indexed Access Types.md b/docs/documentation/ko/handbook-v2/Type Manipulation/Indexed Access Types.md new file mode 100644 index 00000000..6285faf4 --- /dev/null +++ b/docs/documentation/ko/handbook-v2/Type Manipulation/Indexed Access Types.md @@ -0,0 +1,78 @@ +--- +title: Indexed Access Types +layout: docs +permalink: /ko/docs/handbook/2/indexed-access-types.html +oneline: "Type['a'] 구문을 사용해서 타입의 내부 요소에 접근하기" +--- + +타입의 특정 프로퍼티를 찾기 위해서 _인덱싱된 접근 타입_ 을 사용할 수 있습니다. + +```ts twoslash +type Person = { age: number; name: string; alive: boolean }; +type Age = Person["age"]; +// ^? +``` + +인덱싱된 타입은 그 자체로도 타입이라서 유니언, `keyof` 혹은 타입 전체에 사용할 수 있습니다. + +```ts twoslash +type Person = { age: number; name: string; alive: boolean }; +// ---cut--- +type I1 = Person["age" | "name"]; +// ^? + +type I2 = Person[keyof Person]; +// ^? + +type AliveOrName = "alive" | "name"; +type I3 = Person[AliveOrName]; +// ^? +``` + +존재하지 않는 프로퍼티를 인덱싱하려고 하면 오류가 발생합니다. + +```ts twoslash +// @errors: 2339 +type Person = { age: number; name: string; alive: boolean }; +// ---cut--- +type I1 = Person["alve"]; +``` + +또 다른 예로는 임의의 타입을 `number`로 인덱싱해서 배열 요소의 타입을 가져올 수 있습니다. +`typeof`와 결합하면 편리하게 배열 리터럴의 요소 타입을 캡쳐할 수 있습니다. + +```ts twoslash +const MyArray = [ + { name: "Alice", age: 15 }, + { name: "Bob", age: 23 }, + { name: "Eve", age: 38 }, +]; + +type Person = typeof MyArray[number]; +// ^? +type Age = typeof MyArray[number]["age"]; +// ^? +// Or +type Age2 = Person["age"]; +// ^? +``` + +인덱싱할 때 변수 참조를 위해 사용된 `const`는 사용할 수 없고, 오로지 타입만 사용 가능합니다. + + +```ts twoslash +// @errors: 2538 2749 +type Person = { age: number; name: string; alive: boolean }; +// ---cut--- +const key = "age"; +type Age = Person[key]; +``` + +하지만, 비슷한 스타일의 리팩터로 타입 별칭을 사용할 수 있습니다. + +```ts twoslash +type Person = { age: number; name: string; alive: boolean }; +// ---cut--- +type key = "age"; +type Age = Person[key]; +``` diff --git a/docs/documentation/ko/handbook-v2/Type Manipulation/Keyof Type Operator.md b/docs/documentation/ko/handbook-v2/Type Manipulation/Keyof Type Operator.md new file mode 100644 index 00000000..5790a73c --- /dev/null +++ b/docs/documentation/ko/handbook-v2/Type Manipulation/Keyof Type Operator.md @@ -0,0 +1,33 @@ +--- +title: Keyof Type Operator +layout: docs +permalink: /ko/docs/handbook/2/keyof-types.html +oneline: "타입 컨텍스트에서 keyof 연산자 사용하기" +--- + +## `keyof` 타입 연산자 + +`keyof` 연산자는 객체 타입에서 객체의 키 값들을 숫자나 문자열 리터럴 유니언을 생성합니다. +아래 타입 P는 "x" | "y"와 동일한 타입입니다. + +```ts twoslash +type Point = { x: number; y: number }; +type P = keyof Point; +// ^? +``` + +만약 타입이 `string`이나 `number` 인덱스 시그니쳐를 가지고 있다면, `keyof`는 해당 타입을 리턴합니다. + +```ts twoslash +type Arrayish = { [n: number]: unknown }; +type A = keyof Arrayish; +// ^? + +type Mapish = { [k: string]: boolean }; +type M = keyof Mapish; +// ^? +``` + +위 예제에서 주목할 점은 `M`은 `string | number`라는 점입니다. -- JavaScript 객체 키는 항상 문자열을 강제하기 때문에, `obj[0]`은 `obj["0"]`과 동일합니다. + +`keyof` 타입은 우리가 추후에 학습할 매핑된 타입과 함께 사용할 때 특히 유용합니다. diff --git a/docs/documentation/ko/handbook-v2/Type Manipulation/Typeof Type Operator.md b/docs/documentation/ko/handbook-v2/Type Manipulation/Typeof Type Operator.md new file mode 100644 index 00000000..34f8171a --- /dev/null +++ b/docs/documentation/ko/handbook-v2/Type Manipulation/Typeof Type Operator.md @@ -0,0 +1,70 @@ +--- +title: Typeof Type Operator +layout: docs +permalink: /ko/docs/handbook/2/typeof-types.html +oneline: "타입 컨텍스트에서 typeof 연산자 사용하기." +--- + +## `typeof` 타입 연산자 + +JavaScript에서는 이미 _표현식_ 컨텍스트에서 사용할 수 있는 `typeof` 연산자가 있습니다. + +```ts twoslash +// "string"을 출력합니다 +console.log(typeof "Hello world"); +``` + +TypeScript는 _타입_ 컨텍스트에서 변수나 프로퍼티의 타입을 추론할 수 있는 `typeof` 연산자를 추가합니다. + +```ts twoslash +let s = "hello"; +let n: typeof s; +// ^? +``` + +기본 타입에 대해선 별로 유용하진 않지만, 다른 타입 연산자와 함께 `typeof`를 사용하여 많은 패턴을 편리하게 표현할 수 있습니다. +예를 들어, 미리 정의된 타입인 `ReturnType` 부터 살펴보겠습니다. +위 타입은 _함수 타입_ 을 받으면서 반환되는 타입을 제공합니다. + +```ts twoslash +type Predicate = (x: unknown) => boolean; +type K = ReturnType; +// ^? +``` + +함수 이름에 `ReturnType`을 사용하면, 안내 오류를 확인할 수 있습니다. + +```ts twoslash +// @errors: 2749 +function f() { + return { x: 10, y: 3 }; +} +type P = ReturnType; +``` + +_값_ 과 _타입_ 은 같지 않다는 것을 명심하세요. +_값 `f`_ 의 _타입_ 을 추론하기 위해서 `typeof`를 사용합니다. + +```ts twoslash +function f() { + return { x: 10, y: 3 }; +} +type P = ReturnType; +// ^? +``` + +### 제한 + +TypeScript는 `typeof`를 사용할 수 있는 표현식의 종류를 의도적으로 제한합니다. + +특히, 식별자(예: 변수이름) 혹은 프로퍼티에서만 `typeof`를 사용할 수 있습니다. +실행 중인 것으로 생각되는 코드 작성의 실수를 피하는데 도움을 줄 수 있지만, 그렇진 않습니다. + +```ts twoslash +// @errors: 1005 +declare const msgbox: () => boolean; +// type msgbox = any; +// ---cut--- +// Meant to use = ReturnType +let shouldContinue: typeof msgbox("Are you sure you want to continue?"); +``` diff --git a/docs/documentation/ko/handbook-v2/Understanding Errors.md b/docs/documentation/ko/handbook-v2/Understanding Errors.md index c86b6eca..91884b5d 100644 --- a/docs/documentation/ko/handbook-v2/Understanding Errors.md +++ b/docs/documentation/ko/handbook-v2/Understanding Errors.md @@ -14,17 +14,17 @@ TypeScript의 타입 시스템은 구조적이기 때문에, 문제를 발견한 오류 메시지에서 자주 등장하는 용어를 알면 이해하는 데 도움이 됩니다. -#### _할당할 수 있는_ (_assignable to_) +#### *할당할 수 있는* (*assignable to*) -TypeScript는 타입이 다른 타입으로 대체할 수 있을 때 타입을 다른 타입에 _할당할 수_ 있다 라고 표현합니다. -다시 말해 `고양이`는 `동물`을 대체할 수 있기 때문에 `동물`에게 _할당할 수_ 있습니다. +TypeScript는 타입이 다른 타입으로 대체할 수 있을 때 타입을 다른 타입에 *할당할 수* 있다 라고 표현합니다. +다시 말해 `고양이`는 `동물`을 대체할 수 있기 때문에 `동물`에게 *할당할 수* 있습니다. 이름에서 보이듯, 이런 관계는 `t`와 `s`의 타입을 검사하여 `t = s;`의 할당 타당성을 확인하는 데 사용됩니다. 또한 두 가지 타입이 상호 작용하는 대부분의 위치에서 확인할 때에도 사용됩니다. -예를 들어, 함수를 호출할 때 각 인수의 타입은 매개 변수로 선언된 유형에 _할당할 수_ 있어야 합니다. +예를 들어, 함수를 호출할 때 각 인수의 타입은 매개 변수로 선언된 유형에 *할당할 수* 있어야 합니다. -비공식적으로 `T is not assignable to S`라고 하면 TypeScript는 "_`T`와 `S`는 호환되지 않는다"_.고 말한다고 생각하면됩니다. -그러나, 이것은 _방향성이 있는_ 관계라는 점에 유의하세요: `S`가 `T`에 할당될 수 있다고 해서 `T`가 `S`에 할당될 수 있는 것은 아닙니다. +비공식적으로 `T is not assignable to S`라고 하면 TypeScript는 "*`T`와 `S`는 호환되지 않는다"*.고 말한다고 생각하면됩니다. +그러나, 이것은 *방향성이 있는* 관계라는 점에 유의하세요: `S`가 `T`에 할당될 수 있다고 해서 `T`가 `S`에 할당될 수 있는 것은 아닙니다. ## 예시들 (Examples) diff --git a/docs/documentation/ko/javascript/Creating DTS files From JS.md b/docs/documentation/ko/javascript/Creating DTS files From JS.md index 0dc5da7e..9e7b0970 100644 --- a/docs/documentation/ko/javascript/Creating DTS files From JS.md +++ b/docs/documentation/ko/javascript/Creating DTS files From JS.md @@ -73,7 +73,7 @@ TypeScript는 .d.ts 파일을 찾기 위한 추가 단계와 함께 `package.jso | :------------------------ | :----------------------------- | | "types" 필드 없음 | "main" 확인 후, index.d.ts 확인 | | "types": "main.d.ts" | main.d.ts | -| "types": "./dist/main.js" | ./main/main.d.ts | +| "types": "./dist/main.js" | ./dist/main.d.ts | type 필드가 없다면, "main"으로 넘어갑니다. diff --git a/docs/documentation/ko/project-config/Configuring Watch.md b/docs/documentation/ko/project-config/Configuring Watch.md index 127bf2ec..fe1ec592 100644 --- a/docs/documentation/ko/project-config/Configuring Watch.md +++ b/docs/documentation/ko/project-config/Configuring Watch.md @@ -45,7 +45,7 @@ translatable: true You can read more about this in [the release notes](/docs/handbook/release-notes/typescript-3-8.html#better-directory-watching-on-linux-and-watchoptions). -## 환경 변수 `TSC_WATCHFILE`을 사용하여 파일 감시 설정 (Configuring file watching using environment variable `TSC_WATCHFILE`) +## 환경 변수 `TSC*WATCHFILE`을 사용하여 파일 감시 설정 (Configuring file watching using environment variable `TSC*WATCHFILE`) 옵션 | 설명 @@ -55,11 +55,11 @@ You can read more about this in [the release notes](/docs/handbook/release-notes `UseFsEvents` | 파일 시스템 이벤트를 사용하는 `fs.watch`를 사용하여 파일 변경/생성/삭제에 대한 알림을 받습니다. (`fs.watch`는 OS마다 다르게 작동할 수 있습니다.) 예를 들어. 리눅스는 watcher 수에 제한이 있으며 `fs.watch`를 사용하여 watcher를 만들지 못하면, `fs.watchFile`를 대신 사용하여 watcher를 만들게 됩니다. `UseFsEventsWithFallbackDynamicPolling` | 이 옵션은 `fs.watch`를 사용하여 감시자를 만들지 못한 경우 폴링이 동적 큐를 통해 수행된다는 것을 제외하고는 `UseFsEvents` 옵션과 비슷합니다.(동적 큐에 대한 것은 `DynamicPriorityPolling`옵션에서 설명하였습니다.). `UseFsEventsOnParentDirectory` | 이 옵션은 `fs.watch`(파일 시스템 이벤트 사용하는)로 파일의 상위 디렉터리를 감시합니다. 다만, CPU 사용량이 늘어나고 정확도는 떨어질 수 있습니다. -default (no value specified) | 환경 변수`TSC_NONPOLLING_WATCHER`가 true로 설정되면 파일의 상위 디렉터리를 감시합니다. (`UseFsEventsOnParentDirectory`와 동일).false 일 때는 `fs.watchFile`을 사용하여 `250ms` 시간 제한과 함께 모든 파일들을 감시합니다. +default (no value specified) | 환경 변수`TSC*NONPOLLING*WATCHER`가 true로 설정되면 파일의 상위 디렉터리를 감시합니다. (`UseFsEventsOnParentDirectory`와 동일).false 일 때는 `fs.watchFile`을 사용하여 `250ms` 시간 제한과 함께 모든 파일들을 감시합니다. -## 환경 변수`TSC_WATCHDIRECTORY`를 사용하여 디렉터리 감시 설정 (Configuring directory watching using environment variable `TSC_WATCHDIRECTORY`) +## 환경 변수`TSC*WATCHDIRECTORY`를 사용하여 디렉터리 감시 설정 (Configuring directory watching using environment variable `TSC*WATCHDIRECTORY`) -기본적으로 node에서 디렉터리의 재귀적인 감시를 지원하지 않는 플랫폼에서, 디렉터리 감시 기능은 `TSC_WATCHDIRECTORY`에서 선택한 다양한 옵션을 사용하여 하위 디렉터리에 대한 디렉터리 watcher를 재귀적으로 생성함으로써 지원됩니다. 기본적으로 재귀 디렉터리 감시(예: windows)를 지원하는 플랫폼에서는 이 환경 변수의 값이 무시됩니다. +기본적으로 node에서 디렉터리의 재귀적인 감시를 지원하지 않는 플랫폼에서, 디렉터리 감시 기능은 `TSC*WATCHDIRECTORY`에서 선택한 다양한 옵션을 사용하여 하위 디렉터리에 대한 디렉터리 watcher를 재귀적으로 생성함으로써 지원됩니다. 기본적으로 재귀 디렉터리 감시(예: windows)를 지원하는 플랫폼에서는 이 환경 변수의 값이 무시됩니다. 옵션 | 설명 diff --git a/docs/documentation/ko/project-config/Integrating with Build Tools.md b/docs/documentation/ko/project-config/Integrating with Build Tools.md index 842c7286..f5be39b2 100644 --- a/docs/documentation/ko/project-config/Integrating with Build Tools.md +++ b/docs/documentation/ko/project-config/Integrating with Build Tools.md @@ -182,7 +182,7 @@ gulp.task("default", function () { npm install -g jspm@beta ``` -_주의사항: 현재 jspm의 TypeScript 지원은 0.16beta 입니다._ +*주의사항: 현재 jspm의 TypeScript 지원은 0.16beta 입니다.* 자세한 내용: [TypeScriptSamples/jspm](https://github.com/Microsoft/TypeScriptSamples/tree/master/jspm) diff --git a/docs/documentation/ko/reference/Declaration Merging.md b/docs/documentation/ko/reference/Declaration Merging.md index db742ded..8b2cee96 100644 --- a/docs/documentation/ko/reference/Declaration Merging.md +++ b/docs/documentation/ko/reference/Declaration Merging.md @@ -92,7 +92,7 @@ interface Cloner { 각 그룹의 요소는 동일한 순서를 유지하지만, 그룹 자체는 나중에 오버로드 될수록 첫 번째에 위치하는 것에 유의하세요. 이 규칙엔 특수 시그니처(specialized signatures)라는 예외가 존재합니다. -만약 _단일_ 문자열 리터럴 타입(예. 문자열 리터럴이 유니온이 아닌 경우)인 매개변수가 있을 경우, 시그니처는 병합된 오버로드 목록의 맨 위로 올라오게 됩니다. +만약 *단일* 문자열 리터럴 타입(예. 문자열 리터럴이 유니온이 아닌 경우)인 매개변수가 있을 경우, 시그니처는 병합된 오버로드 목록의 맨 위로 올라오게 됩니다. 예를 들어, 아래의 인터페이스들이 병합됩니다: diff --git a/docs/documentation/ko/reference/Decorators.md b/docs/documentation/ko/reference/Decorators.md index fb857f99..6b6129cc 100644 --- a/docs/documentation/ko/reference/Decorators.md +++ b/docs/documentation/ko/reference/Decorators.md @@ -155,7 +155,7 @@ first(): called 클래스 데코레이터가 값을 반환하면 클래스가 선언을 제공하는 생성자 함수로 바꿉니다. > 참고  새 생성자 함수를 반환하도록 선택한 경우 원래 프로토타입을 유지 관리해야 합니다. -런타임에 데코레이터를 적용하는 로직은 이 기능을 **대신해주지 않습니다.** +> 런타임에 데코레이터를 적용하는 로직은 이 기능을 **대신해주지 않습니다.** 다음은 `BugReport` 클래스에 적용된 클래스 데코레이터 (`@sealed`)의 예입니다. @@ -214,7 +214,7 @@ const bug = new BugReport("Needs dark mode"); console.log(bug.title); // Prints "Needs dark mode" console.log(bug.type); // Prints "report" -// Note that the decorator _does not_ change the TypeScript type +// Note that the decorator *does not* change the TypeScript type // and so the new property `reportingURL` is not known // to the type system: bug.reportingURL; @@ -283,8 +283,8 @@ function enumerable(value: boolean) { 접근자 데코레이터는 선언 파일이나 다른 주변 컨텍스트(예: `선언` 클래스)에서 사용할 수 없습니다. > 참고  TypeScript는 단일 멤버에 대해 `get` 및 `set` 접근자를 데코레이팅 할 수 없습니다. -대신 멤버의 모든 데코레이터를 문서 순서대로 지정된 첫 번째 접근자에 적용해야 합니다. -왜냐하면, 데코레이터는 각각의 선언이 아닌 `get`과 `set` 접근자를 결합한 *프로퍼티 설명자*에 적용되기 때문입니다. +> 대신 멤버의 모든 데코레이터를 문서 순서대로 지정된 첫 번째 접근자에 적용해야 합니다. +> 왜냐하면, 데코레이터는 각각의 선언이 아닌 `get`과 `set` 접근자를 결합한 *프로퍼티 설명자*에 적용되기 때문입니다. 접근자 데코레이터의 표현 식은 런타임에 다음 세 가지 인수와 함께 함수로 호출됩니다: @@ -354,8 +354,8 @@ function configurable(value: boolean) { 2. 멤버의 이름 > 참고  TypeScript에서 `프로퍼티 데코레이터`가 초기화되는 방식으로 인해 *프로퍼티 설명자*가 프로퍼티 데코레이터에 대한 인수로 제공되지 않습니다. -현재 프로토타입의 멤버를 정의할 때 인스턴스 프로퍼티를 설명하는 메커니즘이 없고 프로퍼티의 이니셜라이저를 관찰하거나 수정할 수 있는 방법이 없기 때문입니다. 반환 값도 무시됩니다. -따라서 프로퍼티 데코레이터는 특정 이름의 프로퍼티가 클래스에 선언되었음을 관찰하는 데만 사용할 수 있습니다. +> 현재 프로토타입의 멤버를 정의할 때 인스턴스 프로퍼티를 설명하는 메커니즘이 없고 프로퍼티의 이니셜라이저를 관찰하거나 수정할 수 있는 방법이 없기 때문입니다. 반환 값도 무시됩니다. +> 따라서 프로퍼티 데코레이터는 특정 이름의 프로퍼티가 클래스에 선언되었음을 관찰하는 데만 사용할 수 있습니다. 이 정보를 사용하여 다음 예와 같이 프로퍼티에 대한 메타데이터를 기록할 수 있습니다: @@ -396,7 +396,7 @@ function getFormat(target: any, propertyKey: string) { `getFormat`이 호출되면 형식의 메타데이터 값을 읽습니다. > 참고  이 예제에는 `reflect-metadata` 라이브러리가 필요합니다. -`reflect-metadata` 라이브러리에 대한 자세한 내용은 [메타데이터](#메타데이터-metadata)를 참조하십시오. +> `reflect-metadata` 라이브러리에 대한 자세한 내용은 [메타데이터](#메타데이터-metadata)를 참조하십시오. ## 매개변수 데코레이터 (Parameter Decorators) @@ -478,7 +478,7 @@ function validate(target: any, propertyName: string, descriptor: TypedPropertyDe 그런 다음 `@validate` 데코레이터는 원래 메서드를 호출하기 전에 인수 유효성 검증하는 함수로 기존의 `greet` 메서드를 감쌉니다. > 참고  이 예제에는 `reflect-metadata` 라이브러리가 필요합니다. -`reflect-metadata` 라이브러리에 대한 자세한 내용은 [메타데이터] (#메타데이터-metadata)를 참조하십시오. +> `reflect-metadata` 라이브러리에 대한 자세한 내용은 [메타데이터] (#메타데이터-metadata)를 참조하십시오. ## 메타데이터 (Metadata) diff --git a/docs/documentation/ko/reference/Iterators and Generators.md b/docs/documentation/ko/reference/Iterators and Generators.md index eced3fa0..e5413b34 100644 --- a/docs/documentation/ko/reference/Iterators and Generators.md +++ b/docs/documentation/ko/reference/Iterators and Generators.md @@ -27,7 +27,7 @@ for (let entry of someArray) { ### `for..of` vs. `for..in`문 -`for..of`와 `for..in`문은 모두 리스트를 반복하지만 반복하는 값이 다릅니다. `for..in`은 반복하는 객체의 _키_ 리스트를 반환하지만 `for..of`는 반복하는 객체의 숫자 프로퍼티인 _값_ 리스트를 반환합니다. +`for..of`와 `for..in`문은 모두 리스트를 반복하지만 반복하는 값이 다릅니다. `for..in`은 반복하는 객체의 *키* 리스트를 반환하지만 `for..of`는 반복하는 객체의 숫자 프로퍼티인 *값* 리스트를 반환합니다. 다음은 이러한 차이를 보여주는 예시입니다: diff --git a/docs/documentation/ko/reference/JSX.md b/docs/documentation/ko/reference/JSX.md index 8e4096df..66796fb4 100644 --- a/docs/documentation/ko/reference/JSX.md +++ b/docs/documentation/ko/reference/JSX.md @@ -65,7 +65,7 @@ JSX를 통한 타입 검사를 이해하기 위해서는 먼저 내장 요소와 1. React에서 내장 요소는 문자열 (`React.createElement("div")`)로 방출되지만 생성한 구성 요소는 (`React.createElement(MyComponent)`)가 아닙니다. 2. JSX 요소에 전달되는 속성의 타입은 다르게 조회되어야 합니다. - 내장 요소의 속성은 _내재적으로_ 알려져야 하지만, 컴포넌트는 각자의 속성 집합을 지정하고자 합니다. + 내장 요소의 속성은 *내재적으로* 알려져야 하지만, 컴포넌트는 각자의 속성 집합을 지정하고자 합니다. TypeScript는 이를 구분하기 위해 [React와 같은 규칙](http://facebook.github.io/react/docs/jsx-in-depth.html#html-tags-vs.-react-components)을 사용합니다. 내장 요소는 항상 소문자로 시작하고, 값-기반 요소는 항상 대문자로 시작합니다. @@ -74,7 +74,7 @@ TypeScript는 이를 구분하기 위해 [React와 같은 규칙](http://faceboo 내장 요소는 특별한 인터페이스인 `JSX.IntrinsicElements`에서 조회됩니다. 기본적으로 인터페이스가 지정되지 않으면 그대로 진행되어 내장 함수는 타입 검사가 이루어지지 않을 것입니다. -그러나 이 인터페이스가 _있는_ 경우 내장 함수의 이름이 `JSX.IntrinsicElements` 인터페이스에 있는 프로퍼티로 조회됩니다. +그러나 이 인터페이스가 *있는* 경우 내장 함수의 이름이 `JSX.IntrinsicElements` 인터페이스에 있는 프로퍼티로 조회됩니다. 예를 들어: ```ts @@ -166,9 +166,9 @@ function MainButton(prop: SideProps): JSX.Element { ### 클래스형 컴포넌트 클래스형 컴포넌트 타입을 정의하는 것도 가능합니다. -하지만 이를 위해서는 _요소 클래스 타입(element class type)_ 과 _요소 인스턴스 타입(element instance type)_이라는 두 가지 용어를 이해하는 것이 좋습니다. +하지만 이를 위해서는 *요소 클래스 타입(element class type)* 과 *요소 인스턴스 타입(element instance type)*이라는 두 가지 용어를 이해하는 것이 좋습니다. -``가 주어지면, _요소 클래스 타입_은 `Expr`타입입니다. +``가 주어지면, *요소 클래스 타입*은 `Expr`타입입니다. 따라서 위의 예시에서 `MyComponent`가 ES6 클래스인 경우, 해당 클래스의 타입은 클래스의 생성자이고 전역입니다. 만약 `MyComponent`가 팩토리 함수인 경우, 해당 클래스의 타입은 해당 함수입니다. @@ -230,7 +230,7 @@ function NotAValidFactoryFunction() { ## 속성 타입 검사 -속성 타입 검사를 위해서는 먼저 _요소 속성 타입_을 결정해야 합니다. +속성 타입 검사를 위해서는 먼저 *요소 속성 타입*을 결정해야 합니다. 이는 내장 요소와 값-기반 요소에서 약간의 차이가 있습니다. 내장 요소의 경우, 요소 속성 타입은 `JSX.IntrinsicElements` 내 프로퍼티의 타입입니다. @@ -247,7 +247,7 @@ declare namespace JSX { ``` 값-기반 요소의 경우, 이는 약간 더 복잡합니다. -요소 속성 타입은 이전에 결정된 _요소 인스턴스 타입_ 의 프로퍼티 타입으로 결정됩니다. +요소 속성 타입은 이전에 결정된 *요소 인스턴스 타입* 의 프로퍼티 타입으로 결정됩니다. 사용할 프로퍼티는 `JSX.ElementAttributesProperty`에 의해 결정됩니다. 이는 단일 프로퍼티로 선언되어야 합니다. 이후에는 해당 프로퍼티의 이름을 사용합니다. @@ -305,8 +305,8 @@ var badProps = {}; ## 자식 타입 검사 -TypeScript 2.3부터, TS는 _자식(children)_ 타입 검사를 도입했습니다. _자식_은 자식 _JSXExpressions_이 속성에 삽입하고자 하는 _요소 속성 타입_의 특수 프로퍼티입니다. -TS가 _props_ 명을 결정하기 위해 `JSX.ElementAttributesProperty`를 사용하는 것과 유사하게, TS는 _자식_ 내의 props명을 결정하기 위하여 `JSX.ElementChildrenAttribute`를 사용합니다. +TypeScript 2.3부터, TS는 *자식(children)* 타입 검사를 도입했습니다. *자식*은 자식 *JSXExpressions*이 속성에 삽입하고자 하는 *요소 속성 타입*의 특수 프로퍼티입니다. +TS가 *props* 명을 결정하기 위해 `JSX.ElementAttributesProperty`를 사용하는 것과 유사하게, TS는 *자식* 내의 props명을 결정하기 위하여 `JSX.ElementChildrenAttribute`를 사용합니다. `JSX.ElementChildrenAttribute` 는 단일 프로퍼티로 정의되어야만 합니다. ```ts @@ -334,7 +334,7 @@ const CustomComp = (props) =>
{props.children}
``` -다른 속성과 같이_자식_의 타입도 지정할 수 있습니다. 예를 들어서 [React 타이핑](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react)을 사용하는 경우, 이는 기본 타입을 오버라이드 할 것입니다. +다른 속성과 같이*자식*의 타입도 지정할 수 있습니다. 예를 들어서 [React 타이핑](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react)을 사용하는 경우, 이는 기본 타입을 오버라이드 할 것입니다. ```ts interface PropsType { diff --git a/docs/documentation/ko/reference/Module Resolution.md b/docs/documentation/ko/reference/Module Resolution.md index c69c9e62..0eaa97f2 100644 --- a/docs/documentation/ko/reference/Module Resolution.md +++ b/docs/documentation/ko/reference/Module Resolution.md @@ -7,7 +7,7 @@ translatable: true --- > 이번 섹션은 모듈에 대한 기초적인 지식을 전제로 합니다. -더 많은 정보는 [모듈](./modules.md)을 보도록 하세요. +> 더 많은 정보는 [모듈](./modules.md)을 보도록 하세요. *모듈 해석 (module resolution)* 은 컴파일러가 import가 무엇을 참조하는지 알아내기 위해 사용하는 프로세스입니다. `import { a } from "moduleA"`같은 import 문을 생각해보세요; diff --git a/docs/documentation/ko/reference/Namespaces and Modules.md b/docs/documentation/ko/reference/Namespaces and Modules.md index 3030e8ea..a9b7d858 100644 --- a/docs/documentation/ko/reference/Namespaces and Modules.md +++ b/docs/documentation/ko/reference/Namespaces and Modules.md @@ -12,7 +12,7 @@ translatable: true ES 모듈에 대한 자세한 내용은 [모듈](./modules.md) 문서를 참고하세요. TypeScript 네임스페이스에 대한 자세한 내용은 [네임스페이스](./namespaces.md) 문서를 참고하세요. -참고: _매우_ 오래된 버전의 TypeScript 네임스페이스는 이전의 JavaScript 모듈 시스템인 '내부 모듈'이라고 불렸습니다. +참고: *매우* 오래된 버전의 TypeScript 네임스페이스는 이전의 JavaScript 모듈 시스템인 '내부 모듈'이라고 불렸습니다. # 모듈 사용하기 (Using Modules) diff --git a/docs/documentation/ko/reference/Namespaces.md b/docs/documentation/ko/reference/Namespaces.md index 753a2314..3f590de4 100644 --- a/docs/documentation/ko/reference/Namespaces.md +++ b/docs/documentation/ko/reference/Namespaces.md @@ -10,7 +10,7 @@ translatable: true > TypeScript 1.5 버전부터 용어가 변경되었습니다. > "Internal modules" 은 "네임스페이스" 로 변경되었습니다. > "External modules" 은 "모듈" 로 변경되었습니다. 이는 [ECMAScript 2015](http://www.ecma-international.org/ecma-262/6.0/)의 용어와 통일시키기 위함입니다. -(`module X {` 는 현재 선호되는 `namespace X {` 와 동일합니다.) +> (`module X {` 는 현재 선호되는 `namespace X {` 와 동일합니다.) 이 게시물에서는 TypeScript에서 네임스페이스(구 "internal modules")를 사용하여 코드를 구성하는 다양한 방법을 간략하게 설명합니다. 위에서 설명했듯이, "internal modules" 은 "네임스페이스" 로 변경되었습니다. @@ -283,4 +283,4 @@ declare namespace D3 { } declare var d3: D3.Base; -``` \ No newline at end of file +``` diff --git a/docs/documentation/ko/reference/Triple-Slash Directives.md b/docs/documentation/ko/reference/Triple-Slash Directives.md index d202f662..0d556359 100644 --- a/docs/documentation/ko/reference/Triple-Slash Directives.md +++ b/docs/documentation/ko/reference/Triple-Slash Directives.md @@ -16,7 +16,7 @@ translatable: true ## `/// ` `/// `지시어는 가장 일반적인 트리플-슬래시 지시어입니다. - 이 지시어는 파일 간의 _의존성_ 선언으로 사용됩니다. + 이 지시어는 파일 간의 *의존성* 선언으로 사용됩니다. 트리플-슬래시 참조는 컴파일러에게 추가 파일을 컴파일 과정에 포함할 것을 지시합니다. @@ -28,7 +28,7 @@ translatable: true 컴파일러는 모든 트리플-슬래시 참조 지시어를 분석하기 위해 입력 파일에 대해 전처리를 수행합니다. 이 과정 동안, 추가 파일이 컴파일에 추가됩니다. -이 과정은 _root files_ 집합에서 시작됩니다; +이 과정은 *root files* 집합에서 시작됩니다; 이 루트 파일은 명령 줄이나 `tsconfig.json`파일의 `"files"` 목록에 있는 파일 이름입니다. 이러한 파일은 지정된 순서대로 전처리됩니다. 목록에 파일을 추가하기 전에, 파일에 있는 모든 트리플-슬래시 참조가 처리되고, 그 대상들이 포함됩니다. @@ -47,7 +47,7 @@ translatable: true ## `/// ` -_의존성_ 선언 역할을 하는 `/// ` 지시어와 유사하게, `/// ` 지시어는 패키지의 의존성을 선언합니다. +*의존성* 선언 역할을 하는 `/// ` 지시어와 유사하게, `/// ` 지시어는 패키지의 의존성을 선언합니다. 패키지 이름을 처리하는 과정은 `import`문에서 모듈 이름을 처리하는 과정과 유사합니다. 트리플-슬래시-참조-타입 지시어를 선언 패키지의 `import`로 생각하면 이해하기 쉽습니다. @@ -65,9 +65,9 @@ _의존성_ 선언 역할을 하는 `/// ` 지시어와 ## `/// ` -이 지시어는 파일이 명시적으로 기존 내장 _lib_ 파일을 포함하게 합니다.. +이 지시어는 파일이 명시적으로 기존 내장 *lib* 파일을 포함하게 합니다.. -내장 _lib_ 파일은 _tsconfig.json_의 `"lib"` 컴파일러 옵션과 같은 방식으로 참조됩니다 (예.`lib="lib.es2015.d.ts"` 가 아닌 `lib="es2015"` 사용 등). +내장 *lib* 파일은 *tsconfig.json*의 `"lib"` 컴파일러 옵션과 같은 방식으로 참조됩니다 (예.`lib="lib.es2015.d.ts"` 가 아닌 `lib="es2015"` 사용 등). 내장 타입에 의존하는 선언 파일 작성자에게는 트리플-슬래시-참조 lib 지시어를 사용하는 것이 권장됩니다(내장 타입 : DOM APIs 또는 `Symbol`이나 `Iterable`과 같은 내장 JS 런-타임 생성자) 이전에는 이런 .d.ts 파일은 이러한 타입의 전달/중복 선언을 추가했어야 한다. @@ -81,10 +81,10 @@ _의존성_ 선언 역할을 하는 `/// ` 지시어와 ## `/// ` -이 지시어는 파일을 _기본 라이브러리_라고 표시합니다. +이 지시어는 파일을 *기본 라이브러리*라고 표시합니다. `lib.d.ts`와 이를 변형한 것들의 맨 상단에서 볼 수 있습니다. -이 지시어는 컴파일러 기본 라이브러리(예. `lib.d.ts`) 를 컴파일에 포함시키지 _않도록_ 지시합니다. +이 지시어는 컴파일러 기본 라이브러리(예. `lib.d.ts`) 를 컴파일에 포함시키지 *않도록* 지시합니다. 명령 줄에 `--noLib`을 넘겨주는 것과 비슷한 영향을 줍니다. 또한 `--skipDefaultLibCheck`를 넘겨주면, 컴파일러가 `/// `을 갖는 파일은 검사하지 않는다는 것을 유의하세요. diff --git a/docs/documentation/ko/release-notes/TypeScript 3.8.md b/docs/documentation/ko/release-notes/TypeScript 3.8.md index 6855cee2..e3eb22b3 100644 --- a/docs/documentation/ko/release-notes/TypeScript 3.8.md +++ b/docs/documentation/ko/release-notes/TypeScript 3.8.md @@ -5,15 +5,7 @@ permalink: /ko/docs/handbook/release-notes/typescript-3-8.html oneline: TypeScript 3.8 Release Notes --- -* [타입-전용 Imports 와 Exports](#type-only-imports-exports) -* [ECMAScript 비공개 필드](#ecmascript-private-fields) -* [`export * as ns` 구문](#export-star-as-namespace-syntax) -* [최상위-레벨 `await`](#top-level-await) -* [JSDoc 프로퍼티 지정자](#jsdoc-modifiers) -* [리눅스에서 더 나은 디렉터리 감시와 `watchOptions`](#better-directory-watching) -* ["빠르고 느슨한" 증분 검사](#assume-direct-dependencies) - -## 타입-전용 Imports 와 Exports (Type-Only Imports and Exports) +## 타입-전용 Imports 와 Exports (Type-Only Imports and Exports) 이 기능은 대부분의 사용자에겐 생각할 필요가 없을 수도 있지만; `--isolatedModules`, TypeScript의 `transpileModule` API, 또는 Babel에서 문제가 발생하면 이 기능과 관련이 있을 수 있습니다. @@ -68,7 +60,7 @@ import type Foo, { Bar, Baz } from "some-module"; 이 기능에 대한 더 자세한 정보는, `import type`선언이 사용될수 있는 범위를 확대하는 [pull request](https://github.com/microsoft/TypeScript/pull/35200), 와 [관련된 변경 사항](https://github.com/microsoft/TypeScript/pull/36092/)에서 찾을 수 있습니다. -## ECMAScript 비공개 필드 (ECMAScript Private Fields) +## ECMAScript 비공개 필드 (ECMAScript Private Fields) TypeScript 3.8 은 ECMAScript의 [stage-3 클래스 필드 제안](https://github.com/tc39/proposal-class-fields/)의 비공개 필드를 지원합니다. @@ -269,7 +261,7 @@ TypeScript의 `private`프로퍼티 선언에서는, 사용자는 여전히 상 반면에, `#` 비공개 필드는 `WeakMap`을 이용해 다운 레벨 되기 때문에 사용 속도가 느려질 수 있습니다. 어떤 런타임은 `#` 비공개 필드 구현을 최적화 하고, 더 빠른 `WeakMap`을 구현하고 싶을 수 있지만, 모든 런타임에서 그렇지 않을 수 있습니다. -## `export * as ns` 구문 (`export * as ns` Syntax) +## `export * as ns` 구문 (`export * as ns` Syntax) 다른 모듈의 모든 멤버를 하나의 멤버로 내보내는 단일 진입점을 갖는 것은 종종 일반적입니다. @@ -287,7 +279,7 @@ export * as utilities from "./utilities.js"; 이것은 JavaScript에 대한 훌륭한 삶의 질의 향상이며, TypeScript 3.8은 이 구문을 지원합니다. 모듈 대상이 `es2020` 이전인 경우, TypeScript는 첫 번째 줄의 코드 스니펫을 따라서 무언가를 출력할 것입니다. -## 최상위-레벨 `await` (Top-Level `await`) +## 최상위-레벨 `await` (Top-Level `await`) TypeScript 3.8은 "최상위-레벨 `await`"이라는 편리한 ECMAScript 기능을 지원합니다. @@ -325,13 +317,13 @@ export {}; 구현에 관한 더 자세한 정보는 [the original pull request을 확인하세요](https://github.com/microsoft/TypeScript/pull/35813). -## `es2020`용 `target`과 `module` (`es2020` for `target` and `module`) +## `es2020`용 `target`과 `module` (`es2020` for `target` and `module`) TypeScript 3.8은 `es2020`을 `module`과 `target` 옵션으로 지원합니다. 이를 통해 선택적 체이닝 (optional chaining), nullish 병합 (nullish coalescing), `export * as ns` 그리고 동적인 `import(...)` 구문과 같은 ECMAScript 2020 기능이 유지됩니다. 또한 `bigint` 리터럴이 `esnext` 아래에 안정적인 `target`을 갖는 것을 의미합니다. -## JSDoc 프로퍼티 지정자 (JSDoc Property Modifiers) +## JSDoc 프로퍼티 지정자 (JSDoc Property Modifiers) TypeScript 3.8는 `allowJs` 플래그를 사용하여 JavaScript 파일을 지원하고 `checkJs` 옵션이나 `// @ts-check` 주석을 `.js` 파일 맨 위에 추가하여 JavaScript 파일의 *타입-검사*를 지원합니다. @@ -387,7 +379,7 @@ new Foo().stuff++; // 'stuff'는 읽기-전용(read-only) 프로퍼티이기 때문에 할당할 수 없습니다. ``` -## 리눅스에서 더 나은 디렉터리 감시와 `watchOptions` +## 리눅스에서 더 나은 디렉터리 감시와 `watchOptions` TypeScript 3.8에서는 `node_modules`의 변경사항을 효율적으로 수집하는데 중요한 새로운 디렉터리 감시 전략을 제공합니다. @@ -441,7 +433,7 @@ TypeScript의 이전 버전은 폴더에 디렉터리 왓쳐를 *즉시* 설치 이 변경의 더 자세한 내용은 Github으로 이동하여 [the pull request](https://github.com/microsoft/TypeScript/pull/35615)를 읽어보세요. -## "빠르고 느슨한" 증분 검사 +## "빠르고 느슨한" 증분 검사 TypeScript 3.8은 새로운 컴파일러 옵션 `assumeChangesOnlyAffectDirectDepencies`을 제공합니다. 이 옵션이 활성화되면, TypeScript는 정말로 영향을 받은 파일들은 재검사/재빌드하지않고, 변경된 파일뿐만 아니라 직접 import 한 파일만 재검사/재빌드 합니다. diff --git a/docs/documentation/ko/release-notes/TypeScript 3.9.md b/docs/documentation/ko/release-notes/TypeScript 3.9.md index c479ee84..b6aa4eee 100644 --- a/docs/documentation/ko/release-notes/TypeScript 3.9.md +++ b/docs/documentation/ko/release-notes/TypeScript 3.9.md @@ -5,18 +5,7 @@ permalink: /ko/docs/handbook/release-notes/typescript-3-9.html oneline: TypeScript 3.9 Release Notes --- -* [추론과 `Promise.all` 개선](#improvements-in-inference-and-promiseall) -* [속도 향상](#speed-improvements) -* [`// @ts-expect-error` 주석](#-ts-expect-error-comments) -* [조건문에서 호출되지 않은 함수 체크](#uncalled-function-checks-in-conditional-expressions) -* [에디터 개선](#editor-improvements) - * [JavaScript에서 CommonJS 자동-Imports](#commonjs-auto-imports-in-javascript) - * [코드 작업 개행 유지](#code-actions-preserve-newlines) - * [누락된 반환문 빠른 수정](#quick-fixes-for-missing-return-expressions) - * [`tsconfig.json` 파일 "솔루션 스타일" 지원](#support-for-solution-style-tsconfigjson-files) -* [주요 변경 사항](#주요-변경-사항-breaking-changes) - -## 추론과 `Promise.all` 개선 (Improvements in Inference and `Promise.all`) +## 추론과 `Promise.all` 개선 (Improvements in Inference and `Promise.all`) 최신 버전의 TypeScript(약 3.7)는 `Promise.all` 및 `Promise.race`와 같은 함수 선언이 업데이트되었습니다. 안타깝게도, 특히 `null` 또는 `undefined`와 값을 혼합할 때, 약간의 회귀가 발생했습니다. @@ -54,7 +43,7 @@ async function visitZoo(lionExhibit: Promise, sealExhibit: Promise 속도 향상 (Speed Improvements) +## 속도 향상 (Speed Improvements) TypeScript 3.9는 많은 새로운 속도 향상 기능이 포함되어 있습니다. 우리 팀은 material-ui 및 styled-components와 같은 패키지를 사용할 때 편집 / 컴파일 속도가 매우 열악한 것을 확인한 후 성능에 중점을 두었습니다. @@ -76,7 +65,7 @@ TypeScript 3.9는 [컴파일러 및 언어 서비스가 파일 조회를 캐싱 여전히 개선의 여지가 있지만, 이 작업이 모든 사람들에게 보다 빠른 경험으로 이어지기를 바랍니다! -## `// @ts-expect-error` 주석 (`// @ts-expect-error` Comments) +## `// @ts-expect-error` 주석 (`// @ts-expect-error` Comments) TypeScript로 라이브러리를 작성하고 퍼블릭 API의 일부분으로 `doStuff`라는 함수를 export 한다고 상상해보세요. TypeScript 사용자가 타입-체크 오류를 받을 수 있도록 `doStuff` 함수의 타입은 두 개의 `string`을 갖는다고 선언하지만, 또한 JavaScript 사용자에게 유용한 오류를 제공하기 위해 런타임 오류 체크를 합니다 (개발 빌드 시에만 가능). @@ -154,7 +143,7 @@ Unused '@ts-expect-error' directive. * TypeScript의 두 가지 버전 사이에서 업그레이드하는 중이고, 한 버전에서는 코드 오류가 발생하지만 나머지 버전에서는 그렇지 않은 경우 * 솔직히 어떤 옵션 더 나은지 결정할 시간이 없는 경우 -## 조건문에서 호출되지 않은 함수 체크 (Uncalled Function Checks in Conditional Expressions) +## 조건문에서 호출되지 않은 함수 체크 (Uncalled Function Checks in Conditional Expressions) TypeScript 3.7에서 함수 호출을 잊어버렸을 경우 오류를 보고하기 위해 *호출되지 않은 함수 체크*를 도입했습니다. @@ -198,7 +187,7 @@ function getAllFiles(startFileName: string) { https://github.com/microsoft/TypeScript/issues/36048 -## 에디터 개선 (Editor Improvements) +## 에디터 개선 (Editor Improvements) TypeScript 컴파일러는 주요 에디터의 TypeScript 작성 경험뿐만 아니라, Visual Studio 계열 에디터의 JavaScript 작성 경험에도 영향을 줍니다. 에디터에서 새로운 TypeScript/JavaScript 기능을 사용하는 것은 에디터에 따라 다르겠지만 @@ -207,7 +196,7 @@ TypeScript 컴파일러는 주요 에디터의 TypeScript 작성 경험뿐만 * Visual Studio 2017/2019 에는 [SDK 설치 프로그램] 과 [MSBuild 설치](https://www.nuget.org/packages/Microsoft.TypeScript.MSBuild)가 있습니다. * Sublime Text 3은 [다른 버전의 TypeScript 선택]((https://github.com/microsoft/TypeScript-Sublime-Plugin#note-using-different-versions-of-typescript))을 지원합니다. -### JavaScript에서 CommonJS 자동-import (CommonJS Auto-Imports in JavaScript) +### JavaScript에서 CommonJS 자동-import (CommonJS Auto-Imports in JavaScript) CommonJS 모듈을 사용하는 JavaScript 파일에서 자동-import 기능이 크게 개선되었습니다. @@ -230,7 +219,7 @@ const fs = require("fs"); 이 변경에 대한 자세한 내용은, [해당 pull request](https://github.com/microsoft/TypeScript/pull/37027)를 참고하세요. -### 코드 작업 개행 유지 (Code Actions Preserve Newlines) +### 코드 작업 개행 유지 (Code Actions Preserve Newlines) TypeScript의 리팩터링과 빠른 수정은 종종 개행을 유지하는데 큰 역할을 하지는 않았습니다. 기본적인 예로 다음 코드를 보겠습니다. @@ -291,7 +280,7 @@ function printSquares() { [이 pull request](https://github.com/microsoft/TypeScript/pull/36688)에서 구현에 대해 더 자세히 볼 수 있습니다. -### 누락된 반환 문 빠른 수정 (Quick Fixes for Missing Return Expressions) +### 누락된 반환 문 빠른 수정 (Quick Fixes for Missing Return Expressions) 특히 화살표 함수에 중괄호를 추가할 때, 함수의 마지막 문의 값을 반환하는 것을 잊는 경우가 있습니다. @@ -307,7 +296,7 @@ let f2 = () => { 42 } ![TypeScript는 `return` 문을 추가하거나 중괄호를 제거하여 식이 반환되지 않는 오류를 수정합니다.](https://devblogs.microsoft.com/typescript/wp-content/uploads/sites/11/2020/04/missingReturnValue-3-9.gif) -### `tsconfig.json` 파일 "솔루션 스타일" 지원 (Support for "Solution Style" `tsconfig.json` Files) +### `tsconfig.json` 파일 "솔루션 스타일" 지원 (Support for "Solution Style" `tsconfig.json` Files) 에디터는 파일이 어떤 설정 파일에 속하는지 파악하여 적절한 옵션을 적용할 수 있도록 하고 현재 "프로젝트"에 어떤 다른 파일이 포함되어 있는지 파악해야 합니다. 기본적으로, TypeScript의 언어 서버가 영향을 주는 에디터는 각 상위 디렉터리를 따라 올라가 `tsconfig.json`을 찾음으로써 이 작업을 수행합니다. diff --git a/docs/documentation/ko/release-notes/TypeScript 4.0.md b/docs/documentation/ko/release-notes/TypeScript 4.0.md index b1ef23cb..2ec56484 100644 --- a/docs/documentation/ko/release-notes/TypeScript 4.0.md +++ b/docs/documentation/ko/release-notes/TypeScript 4.0.md @@ -340,7 +340,7 @@ class Square { ## 단축 할당 연산자 (Short-Circuiting Assignment Operators) -JavaScript와 많은 언어는 _복합 할당 (compound assignment)_ 연산자라고 불리는 연산자 집합을 지원합니다. +JavaScript와 많은 언어는 *복합 할당 (compound assignment)* 연산자라고 불리는 연산자 집합을 지원합니다. 복합 할당 연산자는 두 개의 인수에 연산자를 적용한 다음 결과를 왼쪽에 할당합니다. 이전에 아래와 같은 것을 본 적이 있을 것입니다: @@ -371,7 +371,7 @@ a <<= b; ``` JavaScript의 많은 연산자에 위와 같은 할당 연산자가 있습니다! -그러나 최근까지도 논리 _and_ 연산자 (`&&`), 논리 _or_ 연산자 (`||`) 및 null과 같은 것을 병합하는 연산자 (nullish coalescing) (`??`)의 세 가지 주목할만한 예외가 있었습니다. +그러나 최근까지도 논리 *and* 연산자 (`&&`), 논리 *or* 연산자 (`||`) 및 null과 같은 것을 병합하는 연산자 (nullish coalescing) (`??`)의 세 가지 주목할만한 예외가 있었습니다. 이것이 TypeScript 4.0이 새로운 할당 연산자`&&=`,`||=`및`??=`를 추가하는 새로운 ECMAScript 기능을 지원하는 이유입니다. @@ -402,7 +402,7 @@ let values: string[]; (values ??= []).push("hello"); ``` -(보세요, 우리가 작성한 _모든_ 코드가 자랑스러운 것은 아닙니다...) +(보세요, 우리가 작성한 *모든* 코드가 자랑스러운 것은 아닙니다...) 드물지만 부수 효과(side-effects)가 있는 getter 또는 setter를 사용하는 경우 이러한 연산자가 필요한 경우에만 할당을 수행한다는 점에 유의할 필요가 있습니다. 그런 의미에서 연산자의 오른쪽이 "단축 (short-circuited)"될 뿐만 아니라 할당 자체도 마찬가지입니다. @@ -419,7 +419,7 @@ if (!obj.prop) { } ``` -[다음 예시를 실행해보세요](https://www.typescriptlang.org/play?ts=Nightly#code/MYewdgzgLgBCBGArGBeGBvAsAKBnmA5gKawAOATiKQBQCUGO+TMokIANkQHTsgHUAiYlChFyMABYBDCDHIBXMANoBuHI2Z4A9FpgAlIqXZTgRGAFsiAQg2byJeeTAwAslKgSu5KWAAmIczoYAB4YAAYuAFY1XHwAXwAaWxgIEhgKKmoAfQA3KXYALhh4EA4iH3osWM1WCDKePkFUkTFJGTlFZRimOJw4mJwAM0VgKABLcBhB0qCqplr63n4BcjGCCVgIMd8zIjz2eXciXy7k+yhHZygFIhje7BwFzgblgBUJMdlwM3yAdykAJ6yBSQGAeMzNUTkU7YBCILgZUioOBIBGUJEAHwxUxmqnU2Ce3CWgnenzgYDMACo6pZxpYIJSOqDwSkSFCYXC0VQYFi0NMQHQVEA) 예시를 통해 _항상_ 할당을 수행하는 것과 어떻게 다른지 확인해보세요. +[다음 예시를 실행해보세요](https://www.typescriptlang.org/play?ts=Nightly#code/MYewdgzgLgBCBGArGBeGBvAsAKBnmA5gKawAOATiKQBQCUGO+TMokIANkQHTsgHUAiYlChFyMABYBDCDHIBXMANoBuHI2Z4A9FpgAlIqXZTgRGAFsiAQg2byJeeTAwAslKgSu5KWAAmIczoYAB4YAAYuAFY1XHwAXwAaWxgIEhgKKmoAfQA3KXYALhh4EA4iH3osWM1WCDKePkFUkTFJGTlFZRimOJw4mJwAM0VgKABLcBhB0qCqplr63n4BcjGCCVgIMd8zIjz2eXciXy7k+yhHZygFIhje7BwFzgblgBUJMdlwM3yAdykAJ6yBSQGAeMzNUTkU7YBCILgZUioOBIBGUJEAHwxUxmqnU2Ce3CWgnenzgYDMACo6pZxpYIJSOqDwSkSFCYXC0VQYFi0NMQHQVEA) 예시를 통해 *항상* 할당을 수행하는 것과 어떻게 다른지 확인해보세요. ```ts const obj = { @@ -468,7 +468,7 @@ try { } ``` -The above has some undesirable behavior if we're trying to prevent _more_ errors from happening in our error-handling code! +The above has some undesirable behavior if we're trying to prevent *more* errors from happening in our error-handling code! Because these variables have the type `any` by default, they lack any type-safety which could have errored on invalid operations. That's why TypeScript 4.0 now lets you specify the type of `catch` clause variables as `unknown` instead. @@ -497,7 +497,7 @@ For more details you can [peek at the changes for this feature](https://github.c ## Custom JSX Factories -When using JSX, a [_fragment_](https://reactjs.org/docs/fragments.html) is a type of JSX element that allows us to return multiple child elements. +When using JSX, a [*fragment*](https://reactjs.org/docs/fragments.html) is a type of JSX element that allows us to return multiple child elements. When we first implemented fragments in TypeScript, we didn't have a great idea about how other libraries would utilize them. Nowadays most other libraries that encourage using JSX and support fragments have a similar API shape. @@ -597,7 +597,7 @@ That's why TypeScript 4.0 brings a new refactoring to convert common patterns to ![Converting `a && a.b.c && a.b.c.d.e.f()` to `a?.b.c?.d.e.f.()`](https://devblogs.microsoft.com/typescript/wp-content/uploads/sites/11/2020/08/convertToOptionalChain-4-0.gif) -Keep in mind that while this refactoring doesn't _perfectly_ capture the same behavior due to subtleties with truthiness/falsiness in JavaScript, we believe it should capture the intent for most use-cases, especially when TypeScript has more precise knowledge of your types. +Keep in mind that while this refactoring doesn't *perfectly* capture the same behavior due to subtleties with truthiness/falsiness in JavaScript, we believe it should capture the intent for most use-cases, especially when TypeScript has more precise knowledge of your types. For more details, [check out the pull request for this feature](https://github.com/microsoft/TypeScript/pull/39135). @@ -615,14 +615,14 @@ See [the pull request](https://github.com/microsoft/TypeScript/pull/38523) for m ### Partial Semantic Mode at Startup We've heard a lot from users suffering from long startup times, especially on bigger projects. -The culprit is usually a process called _program construction_. +The culprit is usually a process called *program construction*. This is the process of starting with an initial set of root files, parsing them, finding their dependencies, parsing those dependencies, finding those dependencies' dependencies, and so on. The bigger your project is, the longer you'll have to wait before you can get basic editor operations like go-to-definition or quick info. -That's why we've been working on a new mode for editors to provide a _partial_ experience until the full language service experience has loaded up. +That's why we've been working on a new mode for editors to provide a *partial* experience until the full language service experience has loaded up. The core idea is that editors can run a lightweight partial server that only looks at the current files that the editor has open. -It's hard to say precisely what sorts of improvements you'll see, but anecdotally, it used to take anywhere between _20 seconds to a minute_ before TypeScript would become fully responsive on the Visual Studio Code codebase. +It's hard to say precisely what sorts of improvements you'll see, but anecdotally, it used to take anywhere between *20 seconds to a minute* before TypeScript would become fully responsive on the Visual Studio Code codebase. In contrast, **our new partial semantic mode seems to bring that delay down to just a few seconds**. As an example, in the following video, you can see two side-by-side editors with TypeScript 3.9 running on the left and TypeScript 4.0 running on the right. @@ -630,7 +630,7 @@ As an example, in the following video, you can see two side-by-side editors with When restarting both editors on a particularly large codebase, the one with TypeScript 3.9 can't provide completions or quick info at all. -On the other hand, the editor with TypeScript 4.0 can _immediately_ give us a rich experience in the current file we're editing, despite loading the full project in the background. +On the other hand, the editor with TypeScript 4.0 can *immediately* give us a rich experience in the current file we're editing, despite loading the full project in the background. Currently the only editor that supports this mode is [Visual Studio Code](http://code.visualstudio.com/) which has some UX improvements coming up in [Visual Studio Code Insiders](http://code.visualstudio.com/insiders). We recognize that this experience may still have room for polish in UX and functionality, and we have [a list of improvements](https://github.com/microsoft/TypeScript/issues/39035) in mind. @@ -644,9 +644,9 @@ Auto-import is a fantastic feature that makes coding a lot easier; however, ever One specific issue that we heard from users was that auto-imports didn't work on dependencies that were written in TypeScript - that is, until they wrote at least one explicit import somewhere else in their project. Why would auto-imports work for `@types` packages, but not for packages that ship their own types? -It turns out that auto-imports only work on packages your project _already_ includes. -Because TypeScript has some quirky defaults that automatically add packages in `node_modules/@types` to your project, _those_ packages would be auto-imported. -On the other hand, other packages were excluded because crawling through all your `node_modules` packages can be _really_ expensive. +It turns out that auto-imports only work on packages your project *already* includes. +Because TypeScript has some quirky defaults that automatically add packages in `node_modules/@types` to your project, *those* packages would be auto-imported. +On the other hand, other packages were excluded because crawling through all your `node_modules` packages can be *really* expensive. All of this leads to a pretty lousy getting started experience for when you're trying to auto-import something that you've just installed but haven't used yet. diff --git a/docs/documentation/ko/tutorials/Babel with TypeScript.md b/docs/documentation/ko/tutorials/Babel with TypeScript.md index bb41ff75..4aa99fcb 100644 --- a/docs/documentation/ko/tutorials/Babel with TypeScript.md +++ b/docs/documentation/ko/tutorials/Babel with TypeScript.md @@ -10,7 +10,7 @@ translatable: true 모던 JavaScript 프로젝트를 만들 때, TypeScript에서 JavaScript 파일로 변환하는 올바른 방법에 대해 고민할 수 있습니다. -많은 경우 그 대답은 프로젝트에 따라 _"~에 달려있다"_ 또는 _"누군가 여러분 대신 결정했을지도 모른다`_ 가 될 것입니다. 만약 [tsdx](https://www.npmjs.com/package/tsdx), [Angular](https://angular.io/), [NestJS](https://nestjs.com/)와 같은 기존 프레임워크 또는 [Getting Started](/docs/home)에 언급된 프레임워크를 사용하여 프로젝트를 만들고 있다면 결정은 여러분 손에 달려있습니다. +많은 경우 그 대답은 프로젝트에 따라 *"~에 달려있다"* 또는 *"누군가 여러분 대신 결정했을지도 모른다`* 가 될 것입니다. 만약 [tsdx](https://www.npmjs.com/package/tsdx), [Angular](https://angular.io/), [NestJS](https://nestjs.com/)와 같은 기존 프레임워크 또는 [Getting Started](/docs/home)에 언급된 프레임워크를 사용하여 프로젝트를 만들고 있다면 이 결정은 여러분을 위해 자동으로 처리됩니다. 하지만, 사용할만한 직관적인 방법은 다음과 같습니다: diff --git a/docs/documentation/ko/tutorials/DOM Manipulation.md b/docs/documentation/ko/tutorials/DOM Manipulation.md index 78abf512..83441592 100755 --- a/docs/documentation/ko/tutorials/DOM Manipulation.md +++ b/docs/documentation/ko/tutorials/DOM Manipulation.md @@ -8,19 +8,19 @@ translatable: true # DOM 조작 (DOM Manipulation) -### _`HTMLElement` 타입 탐구_ (_An exploration into the `HTMLElement` type_) +### *`HTMLElement` 타입 탐구* (*An exploration into the `HTMLElement` type*) 표준화 이후 20여 년 동안, JavaScript는 많은 발전을 이루었습니다. 2020년에는 서버, 데이터 사이언스, 그리고 IoT 기기에도 JavaScript를 사용할 수 있지만, 가장 인기 있는 활용 사례는 웹 브라우저인 것을 기억하는 것이 중요합니다. 웹 사이트는 HTML 및/또는 XML 문서로 구성됩니다. 이러한 문서들은 정적이어서, 변하지 않습니다. *문서 객체 모델(DOM)은* 정적 웹 사이트를 기능적으로 작동시키기 위해 브라우저에 의해 구현된 프로그래밍 인터페이스입니다. DOM API를 사용하면 문서의 구조, 스타일, 그리고 내용을 변경할 수 있습니다. API는 매우 강력해서 이를 바탕으로 보다 쉽게 동적인 웹사이트들 개발하기 위해 수많은 프런트엔드 프레임워크(jQuery, React, Angular 등)가 개발되었습니다. -TypeScript는 타입이 있는 JavaScript 상위 집합(superset)이며, DOM API에 대한 타입 정의를 제공합니다. 이러한 정의는 모든 기본 TypeScript 프로젝트에서 쉽게 사용 가능합니다. _lib.dom.d.ts_ 에 있는 2만여 줄의 정의 중에서, 가장 눈에 띄는 것은 `HTMLElement`입니다. 이 타입은 TypeScript를 사용한 DOM 조작의 중축입니다. +TypeScript는 타입이 있는 JavaScript 상위 집합(superset)이며, DOM API에 대한 타입 정의를 제공합니다. 이러한 정의는 모든 기본 TypeScript 프로젝트에서 쉽게 사용 가능합니다. *lib.dom.d.ts* 에 있는 2만여 줄의 정의 중에서, 가장 눈에 띄는 것은 `HTMLElement`입니다. 이 타입은 TypeScript를 사용한 DOM 조작의 중축입니다. > [DOM 타입 정의](https://github.com/microsoft/TypeScript/blob/master/lib/lib.dom.d.ts)에 대한 소스코드는 이곳에서 볼 수 있습니다. ## 기본 예제 (Basic Example) -간단한 예시 파일 _index.html_: +간단한 예시 파일 *index.html*: @@ -48,7 +48,7 @@ p.textContent = "Hello, World!"; app?.appendChild(p); ``` -_index.html_ 페이지를 컴파일하고 실행한 후, HTML 결과: +*index.html* 페이지를 컴파일하고 실행한 후, HTML 결과: ```html
@@ -58,7 +58,7 @@ _index.html_ 페이지를 컴파일하고 실행한 후, HTML 결과: ## `Document` 인터페이스 (The `Document` Interface) -TypeScript 코드의 첫 번째 줄은 전역변수 `document`를 사용하며, 그 변수를 검사하면 _lib.dom.d.ts_ 파일의 `Document` 인터페이스에 의해 정의된 것으로 표시됩니다. 그 코드의 스니펫(snippet)에는 `getElementById`와 `createElement`라는 두 가지 메서드 호출이 포함되어 있습니다. +TypeScript 코드의 첫 번째 줄은 전역변수 `document`를 사용하며, 그 변수를 검사하면 *lib.dom.d.ts* 파일의 `Document` 인터페이스에 의해 정의된 것으로 표시됩니다. 그 코드의 스니펫(snippet)에는 `getElementById`와 `createElement`라는 두 가지 메서드 호출이 포함되어 있습니다. ### `Document.getElementById` @@ -68,11 +68,11 @@ TypeScript 코드의 첫 번째 줄은 전역변수 `document`를 사용하며, getElementById(elementId: string): HTMLElement | null; ``` -문자열 id 요소가 전달되면 `HTMLElement` 또는 `null`이 반환됩니다. 이 메서드는 가장 중요한 타입들 중 하나인 `HTMLElement`를 도입합니다. 이 타입은 다른 모든 요소 인터페이스의 기본 인터페이스 역할을 합니다. 예를 들면, 예제 코드에서 `p` 변수는 `HTMLParagraphElement` 타입입니다. 다음으로, 이 메서드는 `null`을 반환할 수 있다는 점에 유의해야 합니다. 메서드가 실제로 지정된 요소를 찾을 수 있을지 없을지에 따라 확실한 사전 런타임이 될 수 없기 때문입니다. 스니펫 코드의 마지막 줄에는, `appendChild`를 호출하기 위해 새로운 _선택적 체이닝(optional chaining)_ 연산자가 사용되고 있습니다. +문자열 id 요소가 전달되면 `HTMLElement` 또는 `null`이 반환됩니다. 이 메서드는 가장 중요한 타입들 중 하나인 `HTMLElement`를 도입합니다. 이 타입은 다른 모든 요소 인터페이스의 기본 인터페이스 역할을 합니다. 예를 들면, 예제 코드에서 `p` 변수는 `HTMLParagraphElement` 타입입니다. 다음으로, 이 메서드는 `null`을 반환할 수 있다는 점에 유의해야 합니다. 메서드가 실제로 지정된 요소를 찾을 수 있을지 없을지에 따라 확실한 사전 런타임이 될 수 없기 때문입니다. 스니펫 코드의 마지막 줄에는, `appendChild`를 호출하기 위해 새로운 *선택적 체이닝(optional chaining)* 연산자가 사용되고 있습니다. ### `Document.createElement` -이 메서드의 정의는 다음과 같습니다(_deprecated_ 표기된 정의는 생략했습니다): +이 메서드의 정의는 다음과 같습니다(*deprecated* 표기된 정의는 생략했습니다): ```ts createElement(tagName: K, options?: ElementCreationOptions): HTMLElementTagNameMap[K]; @@ -100,7 +100,7 @@ interface HTMLElementTagNameMap { 일부 요소들은 고유한 프로퍼티를 나타내지 않아 `HTMLElement`를 반환하기도 하지만, 그 외 타입 요소들은 고유한 프로퍼티와 메서드를 가지고 특정 인터페이스(`HTMLElement`에서 확장되거나 구현됨)를 반환합니다. -이제, `createElement` 정의의 나머지 부분인 `(tagName: K, options?: ElementCreationOptions): HTMLElementTagNameMap[K]`를 살펴보겠습니다. 첫 번째 인수 `tagName`은 제네릭 매개변수 `K`로 정의됩니다. TypeScript 인터프리터는 이 인수로부터 제네릭 매개변수를 _추론_ 할 수 있는 충분한 성능을 가지고 있습니다. 이는 개발자가 메서드를 사용할 때 실제로 제네릭 매개변수를 지정할 필요가 없음을 의미하며, 어떤 값이 `tagName`인수로 전달되든 간에 `K`로 추론되므로 정의의 나머지 부분에 사용할 수 있을 것입니다. 정확히 무슨 일이 일어나는지를 보면 반환값 `HTMLElementTagNameMap[K]`는 `tagName`인수를 가지고 해당 타입을 반환합니다. 이 정의는 스니펫 코드 `p` 변수에서 `HTMLParagraphElement`타입을 얻는 방법입니다. 그리고 코드가 `document.createElement('a')`였다면, `HTMLAnchorElement`타입의 요소가 됩니다. +이제, `createElement` 정의의 나머지 부분인 `(tagName: K, options?: ElementCreationOptions): HTMLElementTagNameMap[K]`를 살펴보겠습니다. 첫 번째 인수 `tagName`은 제네릭 매개변수 `K`로 정의됩니다. TypeScript 인터프리터는 이 인수로부터 제네릭 매개변수를 *추론* 할 수 있는 충분한 성능을 가지고 있습니다. 이는 개발자가 메서드를 사용할 때 실제로 제네릭 매개변수를 지정할 필요가 없음을 의미하며, 어떤 값이 `tagName`인수로 전달되든 간에 `K`로 추론되므로 정의의 나머지 부분에 사용할 수 있을 것입니다. 정확히 무슨 일이 일어나는지를 보면 반환값 `HTMLElementTagNameMap[K]`는 `tagName`인수를 가지고 해당 타입을 반환합니다. 이 정의는 스니펫 코드 `p` 변수에서 `HTMLParagraphElement`타입을 얻는 방법입니다. 그리고 코드가 `document.createElement('a')`였다면, `HTMLAnchorElement`타입의 요소가 됩니다. ## `Node` 인터페이스 (The `Node` interface) @@ -108,7 +108,7 @@ interface HTMLElementTagNameMap { ### `Node.appendChild` -코드 스니펫의 마지막 줄은 `app?.appendChild(p)`입니다. 이전 섹션(`document.getElementById`)에서는 `app`이 런타임에 null일 가능성이 있기 때문에 _선택적 체이닝(optional chaining)_ 연산자가 여기에 사용된다고 설명했습니다. `appendChild`의 메서드는 다음과 같습니다: +코드 스니펫의 마지막 줄은 `app?.appendChild(p)`입니다. 이전 섹션(`document.getElementById`)에서는 `app`이 런타임에 null일 가능성이 있기 때문에 *선택적 체이닝(optional chaining)* 연산자가 여기에 사용된다고 설명했습니다. `appendChild`의 메서드는 다음과 같습니다: ```ts appendChild(newChild: T): T; @@ -118,7 +118,7 @@ appendChild(newChild: T): T; ## `children`과 `childNodes`의 차이점 (Difference between `children` and `childNodes`) -이전에 이 문서는 `HTMLElement` 인터페이스가 `Node`로부터 확장된 `Element`에서 확장된 개념이라고 설명했습니다. DOM API에는 _자식(children)_ 요소 개념이 있습니다. 예를 들어 HTML에서 `p` 태그는 `div` 요소의 자식입니다. +이전에 이 문서는 `HTMLElement` 인터페이스가 `Node`로부터 확장된 `Element`에서 확장된 개념이라고 설명했습니다. DOM API에는 *자식(children)* 요소 개념이 있습니다. 예를 들어 HTML에서 `p` 태그는 `div` 요소의 자식입니다. ```tsx
@@ -135,7 +135,7 @@ div.childNodes; // NodeList(2) [p, p] ``` -`div` 요소를 찾아낸 후 `children` 프로퍼티는 `HTMLParagraphElements`를 포함하는 `HTMLCollection` 리스트를 반환합니다. `childNodes` 프로퍼티는 위와 유사하게 노드 리스트인 `NodeList`를 반환합니다. 각 `p` 태그는 여전히 `HTMLParagraphElements` 타입이지만, `NodeList`는 추가적으로 `HTMLCollection` 리스트에는 없는 _HTML 노드_ 를 포함할 수 있습니다. +`div` 요소를 찾아낸 후 `children` 프로퍼티는 `HTMLParagraphElements`를 포함하는 `HTMLCollection` 리스트를 반환합니다. `childNodes` 프로퍼티는 위와 유사하게 노드 리스트인 `NodeList`를 반환합니다. 각 `p` 태그는 여전히 `HTMLParagraphElements` 타입이지만, `NodeList`는 추가적으로 `HTMLCollection` 리스트에는 없는 *HTML 노드* 를 포함할 수 있습니다. `p` 태그 중 하나를 제거하여 html을 수정하되 텍스트는 그대로 유지하십시오. @@ -158,7 +158,7 @@ div.childNodes; ## `querySelector`와 `querySelectorAll` 메서드 (The `querySelector` and `querySelectorAll` methods) -두 개의 메서드 모두 고유한 제약 조건 집합에 적합한 돔 요소 리스트를 가져오는 데 좋은 도구입니다. 메서드들은 _lib.dom.d.ts_ 에 다음과 같이 정의되어 있습니다: +두 개의 메서드 모두 고유한 제약 조건 집합에 적합한 돔 요소 리스트를 가져오는 데 좋은 도구입니다. 메서드들은 *lib.dom.d.ts* 에 다음과 같이 정의되어 있습니다: ```ts /** @@ -176,7 +176,7 @@ querySelectorAll(selectors: K): NodeListOf querySelectorAll(selectors: string): NodeListOf; ``` - `querySelectorAll` 정의는 `NodeListOf`라는 새로운 타입을 반환한다는 점을 제외하면 `getElementByTagName`과 유사합니다. 이 반환 타입은 기본적으로 표준 JavaScript 리스트 요소의 맞춤형으로 구현되었습니다. `NodeListOf`를 `E[]`로 바꿔보면 틀림없이 매우 유사한 사용자 경험을 제공할 것입니다. `NodeListOf`는 `length` , `item(index)`, `forEach((value, key, parent) => void)` , 그리고 숫자 인덱스 생성과 같은 프로퍼티 및 메서드만을 구현합니다. 또한, 메서드는 _노드_ 가 아닌 _요소_ 리스트를 반환하며 이는 `.childNodes` 메서드에서 `NodeList`가 반환한 것입니다. 모순처럼 보일 수 있지만, `Element` 인터페이스는 `Node`에서 확장된 점에 유의해야 합니다. + `querySelectorAll` 정의는 `NodeListOf`라는 새로운 타입을 반환한다는 점을 제외하면 `getElementByTagName`과 유사합니다. 이 반환 타입은 기본적으로 표준 JavaScript 리스트 요소의 맞춤형으로 구현되었습니다. `NodeListOf`를 `E[]`로 바꿔보면 틀림없이 매우 유사한 사용자 경험을 제공할 것입니다. `NodeListOf`는 `length` , `item(index)`, `forEach((value, key, parent) => void)` , 그리고 숫자 인덱스 생성과 같은 프로퍼티 및 메서드만을 구현합니다. 또한, 메서드는 *노드* 가 아닌 *요소* 리스트를 반환하며 이는 `.childNodes` 메서드에서 `NodeList`가 반환한 것입니다. 모순처럼 보일 수 있지만, `Element` 인터페이스는 `Node`에서 확장된 점에 유의해야 합니다. 두 개의 메서드가 동작하는 것을 보려면 기존 코드를 다음과 같이 수정하십시오: @@ -193,7 +193,7 @@ const all = document.querySelectorAll("li"); // 모든 li 요소를 포함하는 ## 더 자세히 알고 싶으십니까? (Interested in learning more?) -_lib.dom.d.ts_ 타입 정의에서 가장 좋은 부분은 Mozilla Developer Network (MDN) 문서 사이트에 표기된 타입들을 반영했다는 것입니다. 예를 들어, `HTMLElement` 인터페이스는 MDN에서 [HTMLElement 페이지](https://developer.mozilla.org/docs/Web/API/HTMLElement)에 문서화 되어 있습니다. 이 페이지에는 사용 가능한 모든 프로퍼티, 메서드, 때로는 예시까지 제공합니다. 해당 페이지가 훌륭한 다른 면은 표준 문서에 맞는 링크를 제공한다는 것입니다. 다음은 [HTMLElement의 W3C 권장사항](https://www.w3.org/TR/html52/dom.html#htmlelement)에 대한 링크입니다. +*lib.dom.d.ts* 타입 정의에서 가장 좋은 부분은 Mozilla Developer Network (MDN) 문서 사이트에 표기된 타입들을 반영했다는 것입니다. 예를 들어, `HTMLElement` 인터페이스는 MDN에서 [HTMLElement 페이지](https://developer.mozilla.org/docs/Web/API/HTMLElement)에 문서화 되어 있습니다. 이 페이지에는 사용 가능한 모든 프로퍼티, 메서드, 때로는 예시까지 제공합니다. 해당 페이지가 훌륭한 다른 면은 표준 문서에 맞는 링크를 제공한다는 것입니다. 다음은 [HTMLElement의 W3C 권장사항](https://www.w3.org/TR/html52/dom.html#htmlelement)에 대한 링크입니다. 소스코드 참조: diff --git a/docs/documentation/pt/declaration-files/templates/global-modifying-module.d.ts.md b/docs/documentation/pt/declaration-files/templates/global-modifying-module.d.ts.md new file mode 100644 index 00000000..8ba3bcd0 --- /dev/null +++ b/docs/documentation/pt/declaration-files/templates/global-modifying-module.d.ts.md @@ -0,0 +1,72 @@ +--- +title: "Global: Módulo de modificação" +layout: docs +permalink: /pt/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html +--- + +## _Módulos de modificação global_ + +Um _módulo de modificação global_ altera valores existentes no escopo global quando são importados. +Por exemplo, pode existir uma biblioteca que adiciona novos membros ao `String.prototype` quando importada. +Este padrão é de certa forma perigoso devido a possibilidade de conflitos em tempo de execução, +mas ainda assim podemos escrever um arquivo de declaração para isso. + +## Identificando módulos de modificação global + +Módulos de modificação global são geralmente fáceis de identificar em sua documentação. +No geral, são similares a plugins globais, mas precisam de uma chamada `require` para ativar seus efeitos. + +Você pode ver uma documentação como essa: + +```js +// chamada ao 'require' que não utiliza o valor retornado +var unused = require("magic-string-time"); +/* ou */ +require("magic-string-time"); + +var x = "hello, world"; +// Cria novos métodos em tipos nativos +console.log(x.startsWithHello()); + +var y = [1, 2, 3]; +// Cria novos métodos em tipos nativos +console.log(y.reverseAndSort()); +``` + +Aqui está um exemplo + +```ts +// Definições de tipo para [~NOME DA BIBLIOTECA~] [~NÚMERO DE VERSÃO OPCIONAL~] +// Projeto: [~NOME DO PROJETO~] +// Definições por: [~SEU NOME~] <[~UMA URL PARA VOCÊ~]> + +/*~ Esse é o arquivo de modelo do módulo de modificação global. Você deve renomeá-lo para index.d.ts + *~ e colocá-lo em uma pasta com o mesmo nome do módulo. + *~ Por exemplo, se você estiver escrevendo um arquivo para "super-greeter", este + *~ arquivo deve estar em 'super-greeter/index.d.ts' + */ + +/*~ Observação: Se seu módulo de modificação global é passível de ser chamado ou instanciado, você + *~ precisará combinar os padrões daqui com aqueles arquivos de modelo na classe ou função de módulo + */ + +declare global { + /*~ Aqui, declare coisas que vão no namespace global, ou aumente + *~ as declarações existentes no namespace global + */ + interface String { + fancyFormat(opts: StringFormatOptions): string; + } +} + +/*~ Se seu módulo exporta tipos ou valores, escreva-os como de costume */ +export interface StringFormatOptions { + fancinessLevel: number; +} + +/*~ Por exemplo, declarando um método no módulo (além dos seus efeitos colaterais globais) */ +export function doSomething(): void; + +/*~ Se seu módulo não exportar nada, você precisara dessa linha. Caso contrário, exclua-a */ +export {}; +``` diff --git a/docs/documentation/pt/get-started/TS for Functional Programmers.md b/docs/documentation/pt/get-started/TS for Functional Programmers.md new file mode 100644 index 00000000..b91d7eaf --- /dev/null +++ b/docs/documentation/pt/get-started/TS for Functional Programmers.md @@ -0,0 +1,503 @@ +--- +title: TypeScript para Programadores Funcionais +short: TS para Programadores Funcionais +layout: docs +permalink: /pt/docs/handbook/typescript-in-5-minutes-func.html +oneline: Aprenda Typescript se você tiver uma história com programação funcional +--- + +Typescript começou sua vida numa tentativa de trazer tipos tradicionalmente orientados a objeto para o JavaScript para que os programadores na Microsoft pudessem trazer programas tradicionalmente orientados a objeto para a web. Conforme foi se desenvolvendo, o sistema de tipos do Typescript evoluiu para código modelo escrito por JavaScripters nativos. O sistema resultante é poderoso, interessante e confuso. + +Essa introdução foi desenvolvida para ajudar programadores Haskell ou ML que querem aprender Typescript. Ela descreve como o sistema de tipos do Typescript difere do sistema de tipos do Haskell. Ela também descreve as funcionalidades únicas do sistema de tipos do Typescript que tem ascendência na modelagem de código JavaScript. + +Essa introdução não cobre programação orientada a objeto. Na prática, programação orientada a objeto em Typescript é similar a outras linguagens populares com funcionalidades OO. + +## Pré-requisitos + +Nessa introdução, eu assumo que você tenha os seguintes conhecimentos: + +- Como programar em JavaScript, as boas partes. +- Sintaxe de tipo de uma linguagem descendente do C. + +Se você precisa aprender as boas partes do Javascript, leia [JavaScript: As Boas Partes](https://shop.oreilly.com/product/9780596517748.do). Você pode ser capaz de pular o livro se você sabe como escrever programas em uma linguagem com escopo léxico de chamada-por-valor com muita mutabilidade e não muito mais. [R4RS Scheme](https://people.csail.mit.edu/jaffer/r4rs.pdf) é um bom exemplo. + +[A Linguagem de Programação C++](http://www.stroustrup.com/4th.html) é um bom lugar para aprender sobre sintaxe no estilo C. Diferente do C++, Typescript usa tipos pós-fixados, como: `x: string` ao invés de `string x`. + +## Conceitos que não estão em Haskell + +## Tipos Nativos + +JavaScript define 8 tipos nativos: + +| Type | Explanation | +| ----------- | ---------------------------------------------- | +| `Number` | um ponto flutuante de dupla precisão IEEE 754. | +| `String` | uma string imutável UTF-16. | +| `BigInt` | inteiros no formato de precisão arbitrário. | +| `Boolean` | `true` e `false`. | +| `Symbol` | um valor único usado como uma chave. | +| `Null` | equivalente ao tipo unit. | +| `Undefined` | também equivalente ao tipo unit. | +| `Object` | similar aos records. | + +[Veja a MDN para mais detalhes](https://developer.mozilla.org/docs/Web/JavaScript/Data_structures). + +Typescript tem os tipos primitivos correspondentes para os tipos nativos: + +- `number` +- `string` +- `bigint` +- `boolean` +- `symbol` +- `null` +- `undefined` +- `object` + +### Outros tipos importantes do Typescript + +| Type | Explanation | +| -------------- | ----------------------------------------------------------------- | +| `unknown` | o tipo do topo. | +| `never` | o tipo do final. | +| object literal | eg `{ property: Type }` | +| `void` | um subtipo de `undefined` para ser usado como um tipo de retorno. | +| `T[]` | arrays mutáveis, também escritos como `Array` | +| `[T, T]` | tuplas, que tem tamanho fixado mas são mutáveis | +| `(t: T) => U` | funções | + +Notas: + +4. Sintaxe de funções incluem os nomes dos parâmetros. É bem difícil se acostumar com isso! + + ```ts + let fst: (a: any, b: any) => any = (a, b) => a; + + // ou mais precisamente: + + let fst: (a: T, b: U) => T = (a, b) => a; + ``` + +5. Sintaxe de tipo literal de objeto espelha precisamente a sintaxe de valor de objeto literal: + + ```ts + let o: { n: number; xs: object[] } = { n: 1, xs: [] }; + ``` + +6. `[T, T]` é um subtipo de `T[]`. Isso é diferente em Haskell, onde tuplas não são relacionadas a listas. + +### Tipos em caixas + +Javascript tem tipos em caixas equivalentes aos tipos primitivos que contém métodos que os programadores associam com esses tipos. Typescript reflete isso com, por exemplo, a diferença entre o tipo primitivo `number` e o tipo em caixa `Number`. Os tipos em caixa raramente são necessários, já que seus métodos retornam primitivos. + +```ts +(1).toExponential(); +// é equivalente a +Number.prototype.toExponential.call(1); +``` + +Note que para chamar um método em um numérico literal ele tem que estar entre parênteses para auxiliar o tradutor. + +## Tipagem gradual + +Typescript usa o tipo `any` sempre que não pode dizer qual deveria ser o tipo de uma expressão. Comparado ao `Dynamic`, chamar o `any` de um tipo é um exagero. Ele apenas desativa o verificador de tipo onde quer que apareça. Por exemplo, você pode inserir qualquer valor em um `any[]` sem marcar o valor de nenhuma forma: + +```ts twoslash +// com "noImplicitAny": false no tsconfig.json, anys: any[] +const anys = []; +anys.push(1); +anys.push('oh não'); +anys.push({ qualquer: 'coisa' }); +``` + +E você pode usar expressões do tipo `any` em qualquer lugar: + +```ts +anys.map(anys[1]); // oh não, "oh não" não é uma função +``` + +`any` é contagioso, também — se você inicializar uma variável com uma expressão do tipo `any`, a variável tem o tipo `any` também. + +```ts +let sepsis = anys[0] + anys[1]; // isso poderia significar qualquer coisa +``` + +Para ter um erro quando o Typescript produzir um `any`, use `"noImplicitAny": true`, ou `"strict": true` no `tsconfig.json`. + +## Tipagem estrutural + +Tipagem estrutural é um conceito familiar para a maioria dos programadores funcionais, mesmo que Haskell e a maior parte das MLs não são estrturalmente tipadas. Sua forma básica é bem simples: + +```ts +// @strict: false +let o = { x: 'olá', extra: 1 }; // ok +let o2: { x: string } = o; // ok +``` + +Aqui, o objeto literal `{ x: "hi", extra: 1 }` tem um tipo literal correspondente `{ x: string, extra: number }`. Esse tipo é atribuível à `{ x: string }` já que tem todas as propriedades requisitadas e essas propriedades tem tipos atribíveis. A propriedade extra não tem nenhuma atribuição anterior, apenas forma um subtipo de `{ x: string }`. + +Tipos nomeados apenas dão um nome a um tipo; para propósitos de atribuição não há nenhuma diferença entre o nome de tipo `Um` e a interface de tipo `Dois` abaixo. Eles ambos tem uma propriedade `p: string`. (Nomes de tipos se comportam diferente de interfaces com respeito a definições recursivas e parâmetros de tipo entretanto.) + +```ts twoslash +// @errors: 2322 +type Um = { p: string }; +interface Dois { + p: string; +} +class Tres { + p = 'Olá'; +} + +let x: Um = { p: 'oi' }; +let dois: Dois = x; +dois = new Tres(); +``` + +## Uniões + +Em Typescript, os tipos uniões são marcados. Em outras palavras, eles não são uniões discriminadas como `data` em Haskell. Entretanto, você pode frequentemente discriminar tipos em uma união usando tags nativas ou outras propriedades. + +```ts twoslash +function começar( + arg: string | string[] | (() => string) | { s: string } +): string { + // isso é super comum em Javascript + if (typeof arg === 'string') { + return casoComum(arg); + } else if (Array.isArray(arg)) { + return arg.map(casoComum).join(','); + } else if (typeof arg === 'function') { + return casoComum(arg()); + } else { + return casoComum(arg.s); + } + + function casoComum(s: string): string { + // finalmente, apenas converta uma string para outra string + return s; + } +} +``` + +`string`, `Array` e `Function` têm predicados de tipos nativos, levando convenientemente o tipo objeto para a ramificação `else`. É possível, entretanto, gerar uniões que são difíceis de diferenciar em tempo de execução, para código novo, é melhor construir apenas uniões discriminadas. + +Os seguintes tipos tem predicados nativos: + +| Tipo | Predicado | +| --------- | ---------------------------------- | +| string | `typeof s === "string"` | +| number | `typeof n === "number"` | +| bigint | `typeof m === "bigint"` | +| boolean | `typeof b === "boolean"` | +| symbol | `typeof g === "symbol"` | +| undefined | `typeof undefined === "undefined"` | +| function | `typeof f === "function"` | +| array | `Array.isArray(a)` | +| object | `typeof o === "object"` | + +Note que funções e arrays são objetos em tempo de execução, porém tem seus próprios predicados. + +### Intersecções + +Em adição a uniões, Typescript também tem intersecções: + +```ts twoslash +type Combinada = { a: number } & { b: string }; +type Conflitante = { a: number } & { a: string }; +``` + +`Combinada` tem duas propriedades, `a` e `b`, como se tivessem sido escritas como um único tipo de objeto literal. Intersecções e uniões são recursivas em casos de conflito, então `Conflitante.a: number & string`. + +## Tipos unitários + +Tipos unitários são subtipos de tipos primitivos que contem exatamente um valor primitivo. Por exemplo, a string `foo` tem o mesmo tipo de `"foo"`. Jà que o JavaScript não tem enums nativas, é comum usar um conjunto de strings conhecidas. Uniões de tipos strings literais permitem que o TypeScript ter este padrão: + +```ts twoslash +declare function encher( + s: string, + n: number, + direction: 'esquerda' | 'direita' +): string; + +encher('hi', 10, 'esquerda'); +``` + +Quando necessário, o compilador _extende_ — converte para um super tipo — o tipo unitário para um tipo primitivo, como `"foo"` +para `string`. Isso acontece quando a mutabilidade é usada, que pode atrapalhar o uso de variáveis mutáveis: + +```ts twoslash +// @errors: 2345 +declare function encher( + s: string, + n: number, + direction: 'esquerda' | 'direita' +): string; +// ---cut--- +let s = 'direita'; +encher('hi', 10, s); // error: 'string' is not assignable to '"esquerda" | "direita"' +``` + +Como o erro acontece: + +- `"direita": "direita"` +- `s: string` pois `"direita"` expande para `string` quando atribuída para uma variável mutável. +- `string` não é atribuível para `"esquerda" | "direita"` + +Você pode resolver isso com uma notação de tipo para `s`, porém isso previne atribuições a `s` de variáveis que não são do tipo `"esquerda" | "direita"`. + +```ts twoslash +declare function encher( + s: string, + n: number, + direction: 'esquerda' | 'direita' +): string; +// ---cut--- +let s: 'esquerda' | 'direita' = 'direita'; +encher('hi', 10, s); +``` + +## Conceitos similares a Haskell + +## Tipagem contextual + +TypeScript tem alguns lugares óbvios onde ele pode inferir tipos, como declarações de variáveis: + +```ts twoslash +let s = 'Eu sou uma string!'; +``` + +Mas também infere tipos em alguns outros lugares que você pode não esperar se já trabalhou com outras linguagens com sintaxes baseadas em C: + +```ts twoslash +declare function map(f: (t: T) => U, ts: T[]): U[]; +let sns = map(n => n.toString(), [1, 2, 3]); +``` + +Aqui, `n: number` nesse exemplo também, apesar do fato que `T` e `U` não foram inferidas antes da chamada. Na verdade, antes de `[1,2,3]` ter sido usado para inferir `T=number`, o tipo de retorno de `n => n.toString()` é usado para inferir `U=string`, causando `sns` ter o tipo `string[]`. + +Note que inferência funcionará em qualquer ordem, mas o intellisense só funcionará da direita pra esquerda, então o TypeScript prefere declarar `map` com o array primeiro: + +```ts twoslash +declare function map(ts: T[], f: (t: T) => U): U[]; +``` + +Tipagem contextual também funciona de forma recursiva entre objetos literais, e em tipos unitários que seriam inferidos como `string` ou `number`. E pode inferir tipos de retorno do contexto: + +```ts twoslash +declare function rodar(thunk: (t: T) => void): T; +let i: { inferencia: string } = rodar(o => { + o.inferencia = 'INSIRA O ESTADO AQUI'; +}); +``` + +O tipo de `o` é determinado para ser `{ inferencia: string }` porque + +1. Inicializadores de declaração são contextualmente tipados pela delcaração do + tipo: `{ inference: string }`. +2. O tipo de retorno de uma chamada usa o tipo contextual para inferências, + então o compilador infere que `T={ inferencia: string }`. +3. Arrow functions usam a tipagem contextual para tipar seus parâmetros, + então o compilador entrega `o: { inferencia: string }`. + +E faz isso enquanto você está digitando, para que antes que você digite `o.`, você tem sugestões para a propriedade `inferencia`, junto com qualquer outras propriedades que você teria em um programa real. +Ao todo, essa feature pode fazer com que a inferência do TypeScript pareça um pouco como um motor de unificação de inferência de tipos, mas não é. + +## Apelidos de tipos + +Apelidos de tipos são meros apelidos, assim como `type` em Haskell. O compilador vai tentar usar o nome de apelido onde quer que tenha sido usado no código fonte, mas não vai ter sucesso sempre. + +```ts twoslash +type Tamanho = [number, number]; +let x: Tamanho = [101.1, 999.9]; +``` + +O equivalente mais próximo de `newtype` é uma _intersecção marcada_: + +```ts +type FString = string & { __compileTimeOnly: any }; +``` + +Uma `FString` é como uma string normal, exceto que o compilador pensa que ela tem uma propriedade chamada `__compileTimeOnly` que não existe de fato. Isso significa que `FString` ainda pode ser atribuída para string, mas não o inverso. + +## Uniões Discriminadas + +O equivalente mais próximo do `data` é uma união de tipos com propriedades discriminantes, normalmente chamadas de uniões discriminadas no TypeScript: + +```ts +type Forma = + | { tipo: 'circulo'; raio: number } + | { tipo: 'quadrado'; x: number } + | { tipo: 'triangulo'; x: number; y: number }; +``` + +Diferente de Haskell, a marcação, ou discriminante, é apenas uma propriedade em cada objeto de tipo. Cada variante tem uma propriedade idêntica com um tipo unitário diferente. Isso ainda é uma união de tipo normal; o `|` na frente é uma parte opcional da sintaxe de união de tipo. Você pode discriminar os membros de uma união usando código JavaScript normal: + +```ts twoslash +type Forma = + | { tipo: 'circulo'; raio: number } + | { tipo: 'quadrado'; x: number } + | { tipo: 'triangulo'; x: number; y: number }; + +function area(s: Forma) { + if (s.tipo === 'circulo') { + return Math.PI * s.raio * s.raio; + } else if (s.tipo === 'quadrado') { + return s.x * s.x; + } else { + return (s.x * s.y) / 2; + } +} +``` + +Note que o tipo de retorno de `area` é inferido como `number` porque o TypeScript sabe que a função é total. Se alguma variante não é coberta, o tipo de retorno será `number | undefined`. + +Também, diferente de Haskell, propriedades comuns aparecem em qualquer união, então você pode usualmente discriminar múltiplos membros da união: + +```ts twoslash +type Forma = + | { tipo: 'circulo'; raio: number } + | { tipo: 'quadrado'; x: number } + | { tipo: 'triangulo'; x: number; y: number }; +// ---cut--- +function altura(s: Forma) { + if (s.tipo === 'circulo') { + return 2 * s.raio; + } else { + // s.tipo: "quadrado" | "triangulo" + return s.x; + } +} +``` + +## Parâmetros de Tipo + +Como a maioria das linguagens descendentes de C, TypeScript pede a declaração de parâmetros de tipo: + +```ts +function levantarArray(t: T): Array { + return [t]; +} +``` + +Não há requerimento de caso, mas parâmetros de tipo são convencionalmente letras maiúsculas únicas. Parâmetros de tipo também podem ser restritos para um tipo, que se comporta um pouco como restrições de classes: + +```ts +function primeiro(t1: T, t2: T): T { + return t1.length > t2.length ? t1 : t2; +} +``` + +TypeScript pode usualmente inferir argumentos de tipo de uma chamada baseado no tipo dos argumentos, então argumentos de tipo não são usualmente necessários. + +Por TypeScript ser estrutural, ele não precisa de nenhum parâmetro de tipo quanto tanto sistemas nominais. Especificamente, eles não são necessários para fazer uma função polimórfica. Parâmetros de tipo devem ser usados apenas para _propagar_ informação de tipo, como restringir parâmetros para serem do mesmo tipo: + +```ts +function comprimento>(t: T): number {} + +function comprimento(t: ArrayLike): number {} +``` + +No primeiro `comprimento`, T não é necessário; note que ele só é referenciado uma vez, então não está sendo usado para restringir o tipo do valor de retorno ou de outros parâmetros. + +### Tipos superiores + +TypeScript não tem tipos superiores, então o seguinte não é permitido: + +```ts +function comprimento, U>(m: T) {} +``` + +### Programação livre de pontos + +Programação livre de pontos — uso pesado de currying e composição de funções — é possível em JavaScript, mas pode ser verboso. Em TypeScript, a inferência de tipo falha frequentemente para programas livres de pontos, então você vai acabar especificando os parâmetros de tipo ao invés de parâmetros de valor. O resultado é tão verboso que é usualmente melhor evitar progamação livre de pontos. + +## Sistema de módulos + +A sintaxe moderna de módulos do JavaScript é parecida com a de Haskell, exceto que qualquer arquivo com `import` ou `export` é implicitamente um módulo: + +```ts +import { value, Type } from 'npm-package'; +import { other, Types } from './local-package'; +import * as prefix from '../lib/third-package'; +``` + +Você também pode importar módulos commonjs — módulos escritos usando o sistema de móudlos do node.js: + +```ts +import f = require('single-function-package'); +``` + +Você pode exportar com uma lista de exportação: + +```ts +export { f }; + +function f() { + return g(); +} +function g() {} // g is not exported +``` + +Ou marcando cada export individualmente: + +```ts +export function f { return g() } +function g() { } +``` + +O último é mais comum mas ambos são permitidos, mesmo quando no mesmo arquivo. + +## `readonly` e `const` + +Em JavaScript, mutabilidade é o padrão, embora ele permita declarações de variáveis com `const` para declarar que _referência_ é mutável. O refernte ainda é mutável: + +```js +const a = [1, 2, 3]; +a.push(102); // ): +a[0] = 101; // D: +``` + +TypeScript tem o modificador adicional `readonly` para propriedades. + +```ts +interface Rx { + readonly x: number; +} +let rx: Rx = { x: 1 }; +rx.x = 12; // erro +``` + +Ele também conta com um tipo mapeado `Readonly` que faz todas as propriedades serem `readonly`: + +```ts +interface X { + x: number; +} +let rx: Readonly = { x: 1 }; +rx.x = 12; // erro +``` + +E tem um tipo específico `ReadonlyArray` que remove métodos de efeitos colaterais e previne escrita aos índices do array, assim como sintaxe especial para este tipo: + +```ts +let a: ReadonlyArray = [1, 2, 3]; +let b: readonly number[] = [1, 2, 3]; +a.push(102); // erro +b[0] = 101; // erro +``` + +Você também pode usar assertividade constante, que opera em objetos literais e arrays: + +```ts +let a = [1, 2, 3] as const; +a.push(102); // erro +a[0] = 101; // erro +``` + +Entretanto, nenhuma dessas opções são o padrão, então elas não são consistentemente usadas em código TypeScript + +## Próximos Passos + +Essa documentação é uma resumo de alto nível da sintaxe e tipos qeu você usaria em código no dia-a-dia. Daqui você deve: + +- Ler o Handbook completo [from start to finish](/docs/handbook/intro.html) (30m) +- Explorar os [exemplos do Playground](/play#show-examples) diff --git a/docs/documentation/pt/get-started/TS for JS Programmers.md b/docs/documentation/pt/get-started/TS for JS Programmers.md new file mode 100644 index 00000000..f829babd --- /dev/null +++ b/docs/documentation/pt/get-started/TS for JS Programmers.md @@ -0,0 +1,288 @@ +--- +title: TypeScript para programadores JavaScript +short: TypeScript para programadores JavaScript +layout: docs +permalink: /pt/docs/handbook/typescript-in-5-minutes.html +oneline: Aprenda como o TypeScript extende o JavaScript +--- + +TypeScript tem uma relação incomum com JavaScript. TypeScript oferece todas as features do JavaScript, e uma camada adicional no topo deste: o sistema de tipos do TypeScript. + +Por exemplo, JavaScript oferece primitivos de linguagem como `string` e `number`, mas não checa consistentemente que você atribuiu estes. TypeScript checa. + +Isso significa que seu código JavaScript existente também é código TypeScript. O benefício principal do TypeScript é que ele pode destacar comportamento inesperado no seu código, diminuindo a chance de bugs. + +Este tutorial fornece um resumo do TypeScript, focando no seu sistema de tipos. + +## Tipos por Inferência + +TypeScript conhece a linguagem JavaScript e vai gerar tipos para você em muitos casos. Por exemplo quando criando uma variável e atribuindo à um determinado valor, TypeScript usará o valor como seu tipo. + +```ts twoslash +let olaMundo = 'Olá Mundo'; +// ^? +``` + +Entendendo como o JavaScript funciona, TypeScript pode construir um sistema de tipos que aceita código JavaScript mas tem tipos. Isso oferece um sistema de tipos sem a necessidade de adicionar caracteres extra para fazer com que os tipos sejam explícitos no seu código. É assim que o TypeScript sabe que `olaMundo` é uma `string` no exemplo acima. + +Você já pode ter escrito código JavaScript no Visual Studio Code, e teve auto-complete do editor. Visual Studio Code usa TypeScript por baixo dos panos para tornar mais fácil o trabalho com JavaScript. + +## Definindo Tipos + +Você pode usar uma ampla variedade de tipos de padrões de projetos no JavaScript. Entretanto, alguns padrões de projeto tornam a inferência de tipos automática difícil (por exemplo, padrões que usam programação dinâmica). Para cobrir estes casos, TypeScript suporta uma extensão do JavaScript, que oferece lugares para que você diga ao TypeScript quais deveriam ser os tipos. + +Por exemplo, para criar um objteo com um tipo inferido que inclui `name: string` e `id: number`, você pode escrever: + +```ts twoslash +const usuario = { + nome: 'Hayes', + id: 0 +}; +``` + +Você pode explicitamente descrever a forma desse objeto usando uma declaração de `interface`: + +```ts twoslash +interface Usuario { + nome: string; + id: number; +} +``` + +Você pode então declarar um objeto JavaScript conforme o formato da sua nova `interface` usando a sintaxe `: TypeName` depois da declaração de uma variável: + +```ts twoslash +interface Usuario { + nome: string; + id: number; +} +// ---cut--- +const usuario: Usuario = { + nome: 'Hayes', + id: 0 +}; +``` + +Se você fornecer um objeto que não corresponde a interface que você forneceu, o TypeScript vai te alertar: + +```ts twoslash +// @errors: 2322 +interface Usuario { + nome: string; + id: number; +} + +const usuario: Usuario = { + nomeDeUsuario: 'Hayes', + id: 0 +}; +``` + +Já que o JavaScript suporta classes e programação orientada a objeto, TypeScript também. Você pode usar a declaração de interface com classes: + +```ts twoslash +interface Usuario { + nome: string; + id: number; +} + +class UsuarioConta { + nome: string; + id: number; + + constructor(nome: string, id: number) { + this.nome = nome; + this.id = id; + } +} + +const usuario: Usuario = new UsuarioConta('Murphy', 1); +``` + +Você pode usar interfaces para tipar parâmetros e valores de retorno em funções: + +```ts twoslash +// @noErrors +interface Usuario { + nome: string; + id: number; +} +// ---cut--- +function buscarUsuarioAdmin(): Usuario { + //... +} + +function deletarUsuario(usuario: Usuario) { + // ... +} +``` + +Já há um pequeno conjunto de tipos primitivos disponíveis em JavaScript: `boolean`, `bigint`, `null`, `number`, `string`, `symbol`, e `undefined`, que você pode usar em uma interface. TypeScript extende essa lista com mais alguns como `any` (permitir qualquer coisa), [`unknown`](/play#example/unknown-and-never) (garanta que alguém usando esse tipo declare qual tipo é), [`never`](/play#example/unknown-and-never) (não é possível que esse tipo aconteça), e `void` (uma função que retorna `undefined` ou que não tem valor de retorno). + +Você verá que há duas sintaxes para construir tipos: [Interfaces e Types](/play/?e=83#example/types-vs-interfaces). Você deve preferir `interface`. Use `type` quando precisar de funcionalidades específicas. + +## Compondo Tipos + +Com TypeScript, você pode criar tipos complexos combinando os simples. Existem duas formas populares de fazer isso: com uniões, e com genéricos. + +### Uniões + +Com uma união, você pode declarar que um tipo pode ser um de muitos. Por exemplo, você pode descrever um tipo `boolean` como sendo `true` ou `false`: + +```ts twoslash +type MeuBooleano = true | false; +``` + +_Nota:_ se você passar o mouse por cima do `MeuBoleano` acima, você verá que é classificado como `boolean`. Essa é uma propriedade do Sistema de Tipos Estruturais. Mais sobre isso abaixo. + +Um caso de uso popular de tipos uniões é para descrever o valor que um conjunto de [literais](/docs/handbook/2/everyday-types.html#literal-types) de `string` ou `number` pode ter: + +```ts twoslash +type EstadoDaJanela = 'aberto' | 'fechado' | 'minimizado'; +type EstadosDeBloqueio = 'trancado' | 'destrancado'; +type NumerosImparesMenoresQue10 = 1 | 3 | 5 | 7 | 9; +``` + +Uniões fornecem uma forma de gerenciar tipos diferentes também. Por exemplo, você pode ter uma função que recebe como argumento um `array` ou uma `string`: + +```ts twoslash +function buscarComprimento(obj: string | string[]) { + return obj.length; +} +``` + +Para saber o tipo de uma variável, use `typeof`: + +| Tipo | Predicado | +| --------- | ---------------------------------- | +| string | `typeof s === "string"` | +| number | `typeof n === "number"` | +| boolean | `typeof b === "boolean"` | +| undefined | `typeof undefined === "undefined"` | +| function | `typeof f === "function"` | +| array | `Array.isArray(a)` | + +Por exemplo, você pode fazer uma função retornar diferentes tipos dependendo se uma string ou um array forem passados: + + +```ts twoslash +function envolverEmArray(obj: string | string[]) { + if (typeof obj === "string") { + return [obj]; +// ^? + } + return obj; +} +``` + +### Genéricos + +Genéricos fornecem variáveis para tipos. Um exemplo comum é um array. Um array sem genéricos pode conter qualquer coisa. Um array com genéricos pode descrever os valores que aquele array contém. + +```ts +type ArrayDeStrings = Array; +type ArrayDeNumeros = Array; +type ObjetoComNomeArray = Array<{ nome: string }>; +``` + +Você pode declarar seus próprios tipos usando genéricos: + +```ts twoslash +// @errors: 2345 +interface Mochila { + adicionar: (obj: Tipo) => void; + buscar: () => Tipo; +} + +// Esse é um atalho para dizer ao Typescript que há uma +// constante chamada mochila, e não se preocupar de onde ela veio. +declare const mochila: Mochila; + +// objeto é uma string, porque nós o declaramos acima como a parte variável de Mochila. +const objeto = mochila.buscar(); + +// Já que a variável mochila é uma string, você não pode passar um número para a função adicionar. +mochila.adicionar(23); +``` + +## Sistema de Tipos Estruturais + +Um dos princípios centrais do TypeScript é que a checagem de tipo é focada no _formato_ que os valores têm. Isso é chamado as vezes de "tipagem do pato" ou "tipagem estrutural". + +Em um sistema de tipagem estruturado, se dois objetos tem o mesmo formato, eles são considerados do mesmo tipo. + +```ts twoslash +interface Ponto { + x: number; + y: number; +} + +function exibirPonto(p: Ponto) { + console.log(`${p.x}, ${p.y}`); +} + +// exibe "12, 26" +const ponto = { x: 12, y: 26 }; +exibirPonto(ponto); +``` + +A variável `ponto` nunca é declarada como sendo do tipo `Ponto`. Entretanto, o TypeScript compara o formato de `ponto` ao formato de `Ponto` na checagem de tipo. Eles têm o mesmo formato, então o código passa. + +A correspondência de tipo só requere que um subconjunto de campos do objeto sejam correspondentes: + +```ts twoslash +// @errors: 2345 +interface Ponto { + x: number; + y: number; +} + +function exibirPonto(p: Ponto) { + console.log(`${p.x}, ${p.y}`); +} +// ---cut--- +const ponto3 = { x: 12, y: 26, z: 89 }; +exibirPonto(ponto3); // logs "12, 26" + +const rect = { x: 33, y: 3, largura: 30, altura: 80 }; +exibirPonto(rect); // logs "33, 3" + +const color = { hex: '#187ABF' }; +exibirPonto(color); +``` + +Não há diferença entre como as classes e os objetos se conformam aos formatos: + +```ts twoslash +// @errors: 2345 +interface Ponto { + x: number; + y: number; +} + +function exibirPonto(p: Ponto) { + console.log(`${p.x}, ${p.y}`); +} +// ---cut--- +class PontoVirtual { + x: number; + y: number; + + constructor(x: number, y: number) { + this.x = x; + this.y = y; + } +} + +const novoPontoV = new PontoVirtual(13, 56); +exibirPonto(novoPontoV); // logs "13, 56" +``` + +Se o objeto ou classe tem todas as propriedades requeridas, TypeScript dirá que eles são correspondentes, independente dos detalhes de implementação. + +## Próximos Passos + +Essa documentação é uma resumo de alto nível da sintaxe e tipos qeu você usaria em código no dia-a-dia. Daqui você deve: + +- Ler o Handbook completo [from start to finish](/docs/handbook/intro.html) (30m) +- Explorar os [exemplos do Playground](/play#show-examples) diff --git a/docs/documentation/pt/get-started/TS for OOPers.md b/docs/documentation/pt/get-started/TS for OOPers.md new file mode 100644 index 00000000..2038e9fd --- /dev/null +++ b/docs/documentation/pt/get-started/TS for OOPers.md @@ -0,0 +1,165 @@ +--- +title: TypeScript para programadores Java/C# +short: TS para programadores Java/C# +layout: docs +permalink: /pt/docs/handbook/typescript-in-5-minutes-oop.html +oneline: Aprenda TypeScript se você tem um background com linguagens orientadas a objeto +--- + +TypeScript é uma escolha popular para programadores acostumados com outras linguagens com tipagem estática, como C# e Java. + +O sistema de tipos do TypeScript oferece muitos dos mesmos benefícios, como melhor conclusão de código, detecção prematura de erros e comuincação mais clara entre partes do seu programa. Enquanto o TypeScript fornece muitas features familiares para esses desenvolvedores, é válido dar um passo atrás para ver o quanto JavaScript (por consequência TypeScript) difere das linguagens orientadas a objeto. Entender essas diferenças vão te ajudar a escrever um código JavaScript melhor e evitar armadilhas comuns que programadores que vão diretamente de C#/Java para TypeScript caem. + +## Co-aprendendo JavaScript + +Se você já é familiar com JavaScript mas é primariamente um programador Java ou C#, essa página introdutória pode ajudar a explicar alguns dos equívocos e armadilhas comuns que você pode estar suscetível. Algumas das formas de modelos de tipo do TypeScript são bem diferentes de Java ou C# e é importante manter esses em mente quando se aprende TypeScript. + +Se você é um desenvolvedor Java ou C# que é novo no JavaScript em geral, nós recomendamos aprender um pouco de JavaScript _sem_ tipos primeiro para entender o comportamento do JavaScript em tempo de execução. Porque o TypeScript não muda a forma que seu código é _executado_, você ainda vai ter que aprender como o JavaScript funciona para escrever código que realmente faz alguma coisa! + +É importante lembrar que TypeScript usa o mesmo _ambiente de execução_ que o JavaScript, então qualquer recursos sobre como realizar determinado comportamento em tempo de execução (converter uma string para um número, exibir um alerta, escrever um arquivo em disco, etc.) vai sempre se aplicar igualmente para programas TypeScript. Não se limite a recursos específicos do TypeScript! + +## Repensando a Classe + +C# e Java são o que podemos chamar de linguagens _obrigatoriamente orientadas a objeto_. Nessas linguagens, a _classe_ é a unidade básica de organização de código e também o recipiente básico de todos os dados _e_ comportamento em tempo de execução. Forçar todas as funcionalidades e dados a serem contidos em classes pode ser um bom modelo de domínio para alguns problemas, mas nem todo domínio _precisa_ ser representado dessa forma. + +### Funções Livres e Dados + +Em JavaScript, funções podem existir em qualquer lugar e dados podem ser enviados livremente sem estar dentro de uma `class` ou `struct` pré definida. Essa flexiblidade é extremamente poderosa. Funções "livres" (aquelas que não são associadas à uma classe) trabalhando sobre os dados sem uma hierarquia de orientação a objeto implicada tendem a ser o modelo preferido para escrever programas em JavaScript. + +### Classes Estáticas + +Adicionalmente, certos construtos de C# e Java tais como singletons e classes estáticas são desnecessários em TypeScript. + +## POO em TypeScript + +Com isso dito, você ainda pode usar classes se quiser! Alguns problemas são adequados a serem resolvidosp por hierarquia de POO tradicional e o suporte do TypeScript a classes JavaScript fará esses modelos ainda mais poderosos. TypeScript suporta muitos padrões comuns tais como implementar interfaces, herança e métodos estáticos. + +Nós cobriremos classes mais tarde neste guia. + +## Repensando Tipos + +O entendimento do TypeScript de um _tipo_ é atualmente bem diferente do de C# ou Java. Vamos explorar algumas diferenças. + +### Sistema de Tipos Nominal Reificado + +Em C# ou Java, qualquer dado valor ou objeto tem um tipo exato - seja `null`, um primitivo, ou uma classe conhecida. Nós podemos chamar métodos como `value.GetType()` ou `value.getClass()` para buscar o tipo exato em tempo de execução. A definição desse tipo vai residir em uma classe em algum lugar com algum nome e nós não podemos usar duas classes com formatos similares no lugar uma da outra a não ser que haja uma relação de herança explícita ou uma interface comum implementada. + +Estes aspectos descrevem um sistema de tipo _nominal, reificado_. Os tipos que escrevemos no código são presentes em tempos de execução e esses tipos são relacionados por suas declarações, não suas estruturas. + +## Tipos como Conjuntos + +Em C# ou Java, é siginficante pensar em uma correspondência um pra um entre os tipos de tempo de execução e suas declarações de tempo de compilação. + +Em TypeScript, é melhor pensar em um tipo como um _conjunto de valores_ que compartilham algo em comum. Por tipos serem apenas conjuntos, um valor particular pode pertencer à _muitos_ conjuntos ao mesmo tempo. + +Uma vez que você começa a pensar em tipos como conjuntos, certas operações se tornam bastante naturais. Por exemplo, em C#, é bem estranho enviar um valor que _pode ser_ uma `string` ou um `int`, porque não há um tipo único que represente este valor. + +Em TypeScript, isso se torna bem natural uma vez que você realiza que todo tipo é apenas um conjunto. Como você descreve um valor que pode pertencer ao conjunto `string` ou ao conjunto `number`? Ele simplesmente pertence à _união_ desses conjuntos: `string | number`. + +TypeScript fornece um número de mecanismos para trabalhar com tipos em forma de conjuntos e você vai descobrir que eles são mais intuitivos se você pensar em tipos como conjuntos. + +### Tipos Estruturais Apagados + +Em TypeScript, objetos _não_ são de um tipo exato. Por Exemplo, se construímos um objeto que satisfaz uma interface, nós podemos usar este objeto onde aquela interface é esperada mesmo que não haja relação delcarativa entre os dois. + +```ts twoslash +interface Ponto { + x: number; + y: number; +} +interface Nomeada { + nome: string; +} + +function exibirPonto(point: Ponto) { + console.log('x = ' + point.x + ', y = ' + point.y); +} + +function exibirNome(x: Nomeada) { + console.log('Olá, ' + x.nome); +} + +const obj = { + x: 0, + y: 0, + nome: 'Origem' +}; + +exibirPonto(obj); +exibirNome(obj); +``` + +O sistema de tipos do TypeScript é _estrutural_, não nominal: Nós podemos usar `obj` como um `Ponto` porque as propriedades `x` e `y` são ambas números. A relação entre os tipos são determinadas pelas propriedades que eles contém, não se foram declarados com determinada relação. + +O sistema de tipos do TypeScript também não é _reificado_: Nâo há nada em tempo de execução que nós dirá se aquele `obj` é um `Ponto`. Na verdade, o tipo `Ponto` não é presente em _nenhuma forma_ em tempo de execução. + +Voltando para a ideia de `tipos como conjuntos`, nós podemos pensar que `obj` é um membro tanto do conjunto de valores `Ponto` quanto do conjunto de valores `Nomeada`. + +### Consequências da Tipagem Estrutural + +Programadores POO são frequentementes surpreendidos pelos aspectos particulares da tipagem estrutural. + +#### Tipos Vazios + +O primeiro é que o _tipo vazio_ parece desafiar as expectativas: + +```ts twoslash +class Vazio {} + +function fn(arg: Vazio) { + // fazer algo? +} + +// Sem erro, mas isso não é um 'Vazio' ? +fn({ k: 10 }); +``` + +TypeScript determina se a chamada para `fn` é válida por checar se o argumento fornecido é um `Vazio` válido. Ele faz isso examinando a `estrutura` de `{ k: 10 }` e `class Vazio { }`. Nós podemos ver que `{ k: 10 }` tem todas as propriedades que `Vazio` tem, porque `Vazio` não tem propriedades. Logo, é uma chamada válida. + +Isso pode parecer muito surpreendente, mas, em última análise, é uma relação muito similar a uma aplicada em linguagens de POO nominais. Uma subclasse não pode _remover_ uma propriedade de sua classe base, porque fazer isso destruiria a relação natural de subtipo entre a classe derivada e sua base. Sistemas de tipagem estrutural simplesmente identificam esse relacionamento implicitamente descrevendo subtipos em termos de tendo propriedades de tipos compatíveis. + +### Tipos Idênticos + +Outra frequente fonte de supresa vem com tipos idênticos: + +```ts +class Carro { + dirigir() { + // pressionar o acelerador + } +} +class Golfer { + dirigir() { + // jogar a bola para longe + } +} + +// Sem erro? +let w: Carro = new Golfer(); +``` + +Novamente, isso não é um erro porque as _estruturas_ dessas classes são as mesmas. Enquanto isso pode parecer como uma potencial fonte de confusão, na prática, classes idênticas que não deveriam ser relacionadas não são comuns. + +Nós aprendemos mais sobre como classes se relacionam umas com as outras no capítulo Classes. + +### Reflexão + +Programadores POO são acostumados a serem capazes de pegar o tipo de qualquer valor, até um genérico: + +```csharp +// C# +static void TipoDoLog() { + Console.WriteLine(typeof(T).Name); +} +``` + +Porque o sistema de tipos do TypeScript é totalmente apagado, informação sobre e.g. a instanciação de um parâmetro de tipo genérico não está disponível em tempo de execução. + +JavaScript tem alguns primitivos limitados como `typeof` e `instanceof`, mas lembre-se que esses operadores ainda funcionarão nos valores porque eles existem no código de saída com tipo apagado. Por exemplo `typeof (new Carro())` será `object`, não `Carro` ou `"Carro"` + +## Próximos Passos + +Essa documentação é uma resumo de alto nível da sintaxe e tipos qeu você usaria em código no dia-a-dia. Daqui você deve: + +- Ler o Handbook completo [from start to finish](/docs/handbook/intro.html) (30m) +- Explorar os [exemplos do Playground](/play#show-examples) diff --git a/docs/documentation/pt/get-started/TS for the New Programmer.md b/docs/documentation/pt/get-started/TS for the New Programmer.md new file mode 100644 index 00000000..3eea392e --- /dev/null +++ b/docs/documentation/pt/get-started/TS for the New Programmer.md @@ -0,0 +1,156 @@ +--- +title: TypeScript para o Novo Programador +short: TS para o Novo Programador +layout: docs +permalink: /pt/docs/handbook/typescript-from-scratch.html +oneline: Aprenda TypeScript do zero +--- + +Parabéns por escolher TypeScript como uma das suas primeiras linguagens - você já está fazendo boas decisões! + +Você provavelmente já deve ter ouvido que TypeScript é um "sabor" ou uma "variante" do JavaScript. O relacionamento entre TypeScript (TS) e JavaScript (JS) é único entre linguagens de programação modernas, então aprender mais sobre esse relacionamento vai te ajudar a entender como TypeScript soma ao JavaScript. + +## O Que é JavaScript? Uma Breve História + +JavaScript (também conhecido como ECMAScript) começou sua vida como uma lingaugem de script simples para navegadores. Na época em que foi inventada, sempre foi esperado que fosse usada para pequenos snippets de código embarcados em uma página web - escrevendo mais do que uma dúzia de linhas de código seria algo incomum. Por isso, navegadores jovens da época executavam tal código bem devagar. Entretanto, com o tempo, JS se tornou mais e mais popular e desenvolvedores web começaram a usar ele para criar experiências interativas. + +Desenvolvedores de navegadores web responderam a esse uso aumentado de JS otimizando seus motores de execução (compilação dinâmica) e extendendo o que poderia ser feito com ele (adicionando APIs), o que por sua vez fez os desenvolvedores web o usarem ainda mais. Em websites modernos, seu browser frequentemente está rodando aplicações que têm centenas de milhares de linhas de código. Esse é o crescimento longo e gradual da "web", começando como uma rede simples de páginas estáticas e evoluindo em uma plataforma para _aplicações_ ricas de todos os tipos. + +Mais do que isso, JS se tornou popular o suficiente para ser usado fora do contexto de navegadores, como a implementação de servidores JS usando node.js. A natureza de "rodar em qualquer lugar" do JS faz ele ser uma escolha atrativa para desenvolvimento multiplataforma. Há muitos desenvolvedores nesses dias que usam _apenas_ JavaScript para programar toda seu conjunto de aplicações! + +Para resumir, nós temos uma linguagem que foi desenvolvida para usos rápidos e então cresceu para uma ferramenta completa para escrever aplicações com milhões de linhas. Toda linguagem tem suas próprias _individualidades_ - uniquicidades e surpresas e o começo humilde do JavaScript faz com que ele tenha _muitas_ dessas. Alguns exemplos: + +- O operador de igualidade do JavaScript (`==`) _coage_ seus argumentos, levando a comportamento inesperado: + + ```js + if ('' == 0) { + // É! mas porque?? + } + if (1 < x < 3) { + // Verdadeiro para qualquer valor de x! + } + ``` + +- JavaScript também permite acessar propriedades que não estão presentes: + + ```js + const obj = { width: 10, height: 15 }; + // Porque isso é NaN? Ortografia é difícil! + const area = obj.width * obj.heigth; + ``` + +A maioria das linguagens de programação lançariam um erro quando esse tipo de situação ocorresse, algumas fariam isso em tempo de compilação - antes de qualquer código estar sendo executado. Quando escrevendo programas pequenos, tais individualidades são irritantes mas gerenciáveis; quando escrevendo aplicações com centenas ou milhares de linhas de código, essas surpresas constantes são um problema sério. + +## TypeScript: Um Verificador de Tipos Estáticos + +Nós dissemos antes que algumas linguagens não permitiriam esses programas bugados nem serem executados. Detecção de erros sem execução do código é chamada de _verificação estática_. Determinar o que é um erro e o que não é baseado nos tipos dos valores sendo operados é chamado de verificação estática de _tipos_. + +TypeScript verifica um programa por erros antes de sua execução e faz isso baseado nos _tipos dos valores_, é um _verificador de tipo estático_. Por exemplo, o último exemplo acima tem um erro por causa do _tipo_ de `obj`. Aqui está o erro que o TypeScript encontra: + +```ts twoslash +// @errors: 2551 +const obj = { width: 10, height: 15 }; +const area = obj.width * obj.heigth; +``` + +### Um Superconjunto Tipado de JavaScript + +Como TypeScript se realaciona com JavaScript então? + +#### Sintaxe + +TypeScript é uma linguagem que é um _superconjunto_ de JavaScript: sintaxe JS é, logo, válida em TS. Sintaxe se refere à forma que escrevemos texto para formar um programa. Por exemplo, este código tem um erro de _sintaxe_ porque falta um `)`: + +```ts twoslash +// @errors: 1005 +let a = (4 +``` + +TypeScript não considera qualquer código JavaScript como um erro por sua sintaxe. Isso significa que você pode pegar qualquer código funcional JavaScript e colocar em um arquivo TypeScript sem se preocupar em como está escrito. + +#### Tipos + +Entretanto, TypeScript é um superconjunto _tipado_, significando que adiciona regras sobre como diferentes tipos de valores podem ser usados. O erro anterior sobre `obj.heigth` não era um erro de _sintaxe_: é um erro de uso de um tipo de valor (um _tipo_) de uma maneira incorreta. + +Como outro exemplo, isso é um código JavaScript que você pode rodar no seu browser e ele _vai_ exibir um valor: + +```js +console.log(4 / []); +``` + +Este programa sintaticamente legal exibe `Infinity`. TypeScript por sua vez considera a divisão de um número por um array uma operação sem sentido e vai exibir um erro: + +```ts twoslash +// @errors: 2363 +console.log(4 / []); +``` + +É possível que você realmente _queira_ dividir um núemro po rum array, talvez só para ver o que acontece, mas na maior parte do tempo isso é um erro de programação. O verificador de tipo do TypeScript é desenvolvido para permitir programas corretos enquanto previne quantos erros comuns forem possíveis. (Mais tarde, aprenderemos sobre configurações que você pode usar para configurar quão estritamente o TypeScript verifica seu código.) + +Se você move algum código de um arquivo JavaScript para um arquivo TypeScript, você pode ver _erros de tipo_ dependendo de como o código é escrito. Esses podem ser problemas legítimos com o código ou TypeScript sendo conservador em excesso. Por meio deste guia nós vamos demonstrar como adicionar várias sintaxes do TypeScript para eliminar tais erros. + +#### Comportamento em Tempo de Execução + +TypeScript também é uma linguagem de programação que preserva o _comportamento de tempo de execução_ do JavaScript. Por exemplo, dividir por zero em JavaScript produz `Infinity` ao invés de lançar um erro em tempo de execução. Como um princípio, o TypeScript **nunca** muda o comporatmento de tempo de execução de código JavaScript. + +Isso significa que você mover código do JavaScript do TypeScript, é **garantido** que vai rodar da mesma forma mesmo que o TypeScript pensa que o código tem erros de tipos. + +Mantendo o mesmo comportamento em tempo de execução que o JavaScript é uma promessa fundamental do TypeScript porque significa que você pode facilmente transitar entre duas linguagens sem se preocupar com diferenças sutis que podem fazer seu programa parar de funcionar. + + + +#### Tipos Apagados + +A grosso modo, uma vez que o compilador do TypeScript terminou de verificar o seu código, ele _apaga_ os tipos para produzir o código resultante "compilado". Isso significa que uma vez que seu código for compilado, o código JS puro de resultado não tem informação de tipo. + +Isso também significa que o TypeScript nunca muda o _comportamento_ do seu programa baseado nos tipos que infere. O fim disso é que enquanto você vê erros de tipo durante a compilação, o sistema de tipos em si não tem influência sobre como seu programa funciona quando roda. + +Finalmente, TypeScript não fornece nenhuma biblioteca de tempo de execução adicional. Seus programas vão usar as mesmas bibliotecas padrão (ou externas) que os programas JavaScript, então não há ferramentas específicas do TypeScript adicionais para se aprender. + + + +## Aprendendo JavaScript e TypeScript + +Nós frequentemente vemos a questão "Eu deveria aprender JavaScript ou TypeScript?". + +A resposta é que vocẽ não pode aprender TypeScript sem aprender JavaScript! TypeScript compartilha sintaxe e comportamento de tempo de execução com JavaScript, então qualquer coisa que você queira aprender sobre JavaScript estará ajudando você a aprender TypeScript ao mesmo tempo. + +Hà muitos, muitos recursos disponíveis para programadores aprenderem JavaScript; você _não_ deveria ignorar estes recursos se você está escrevendo TypeScript. Por exemplo, há cerca de 20 vezes mais questões no StackOverflow marcadas com `javascript` do que com `typescript`, mas _todas_ as questões `javascript` também se aplicam ao TypeScript. + +Se você se encontra procurando por algo como "como organizar uma lista em TypeScript", lembre-se: **TypeSript é o ambiente de execução do JavaScript com verificador de tipo em tempo de compilação**. A forma com que você organiza uma lista em TypeScript é a mesma no JavaScript. Se você encontrar um recurso que usa TypeScript diretamente isso é ótimo também, mas não se limite a pensar que você precisa de respostas específicas do TypeScript para questões do dia a dia sobre como alcançar tarefas do ambiente de execução. + +## Próximos Passos + +Esse foi um pequeno resumo da sintaxe e ferramentas usadas no TypeScript no dia-a-dia. Daqui, você pode: + +- Aprender alguns fundamentos do JavaScript, nós recomendamos: + + - [Microsoft's JavaScript Resources](https://docs.microsoft.com/javascript/) or + - [JavaScript guide at the Mozilla Web Docs](https://developer.mozilla.org/docs/Web/JavaScript/Guide) + +- Continuar para [TypeScript para programadores JavaScript](/docs/handbook/typescript-in-5-minutes.html) +- Ler o Handbook completo [from start to finish](/docs/handbook/intro.html) (30m) +- Explorar os [exemplos do Playground](/play#show-examples) + + + diff --git a/docs/documentation/zh/get-started/TS for JS Programmers.md b/docs/documentation/zh/get-started/TS for JS Programmers.md new file mode 100644 index 00000000..5c6711a3 --- /dev/null +++ b/docs/documentation/zh/get-started/TS for JS Programmers.md @@ -0,0 +1,289 @@ +--- +title: 为 JavaScript 程序员准备的 TypeScript +short: 为 JS 程序员准备的 TypeScript +layout: docs +permalink: /zh/docs/handbook/typescript-in-5-minutes.html +oneline: 学习 TypeScript 对 Javascript 的扩展 +--- + +TypeScript 与 JavaScript 有着不同寻常的关系。TypeScript 提供了 JavaScript 的所有功能,并在这些功能之上添加了一层: TypeScript 的类型系统。 + +例如,JavaScript 提供了诸如 `string` 和 `number` 这样的原始类型,但它不检查你在赋值时与类型是否匹配。TypeScript 提供了这样的功能。 + +这意味着你现有的运行良好的 JavaScript 代码也是 TypeScript 代码。TypeScript 的主要好处是,它可以检查代码中的意外行为,从而降低出现错误的机会。 + +本教程提供 TypeScript 的简要概述,重点介绍其类型系统。 + +## 类型推断 + +TypeScript 可以识别 JavaScript 语言,在许多情况下可以推断类型。例如,在创建变量并将其赋值给特定值时, TypeScript 将使用该值作为其类型。 + +```ts twoslash +let helloWorld = "Hello World"; +// ^? +``` + +通过感知 JavaScript 的工作原理,TypeScript 可以构建一个接受 JavaScript 代码但具有类型的类型系统。这个类型系统使得我们不需要添加额外的字符来显式地指定类型。在上面的例子中,TypeScript就是这样知道 `helloWorld` 是 `string` 类型的。 + +你可能已经在 Visual Studio Code 中编写了 JavaScript,并已使用了编辑器的自动补全功能。Visual Studio Code 使用了 TypeScript 的引擎,以便更容易地处理 JavaScript。 + +## 定义类型 + +你可以在 JavaScript 中使用各种各样的设计模式。然而,某些设计模式使得类型难以自动推断(例如,使用动态编程的模式)。为了使类型推断涵盖这些情况, TypeScript 支持扩展 JavaScript 语言,它可以让 TypeScript 知道如何去推断类型。 + +例如,要创建具有推断类型的对象,该类型包括 `name: string` 和 `id: number`,你可以这么写: + +```ts twoslash +const user = { + name: "Hayes", + id: 0, +}; +``` + +你可以使用 `interface` 关键字声明显式地描述此对象的*内部数据的类型*(译者注:下文可能译为“结构”): + +```ts twoslash +interface User { + name: string; + id: number; +} +``` + +然后你可以声明一个符合此接口(`interface`)的 JavaScript 对象,在变量声明后使用像 `: TypeName` 这样的语法: + +```ts twoslash +interface User { + name: string; + id: number; +} +// ---分割线--- +const user: User = { + name: "Hayes", + id: 0, +}; +``` + +如果提供的对象与提供的接口不匹配,TypeScript 将警告: + +```ts twoslash +// @errors: 2322 +interface User { + name: string; + id: number; +} + +const user: User = { + username: "Hayes", + id: 0, +}; +``` + +由于 JavaScript 支持类和面向对象编程,TypeScript 也支持。你可以将接口声明与类一起使用: + +```ts twoslash +interface User { + name: string; + id: number; +} + +class UserAccount { + name: string; + id: number; + + constructor(name: string, id: number) { + this.name = name; + this.id = id; + } +} + +const user: User = new UserAccount("Murphy", 1); +``` + +您可以使用接口对参数进行注释,并将值返回给函数: + +```ts twoslash +// @noErrors +interface User { + name: string; + id: number; +} +// ---分割线--- +function getAdminUser(): User { + //... +} + +function deleteUser(user: User) { + // ... +} +``` + +JavaScript 中已经有一些基本类型可用:`boolean`、 `bigint`、 `null`、`number`、 `string`、 `symbol ` 和 `undefined`,它们都可以在接口中使用。TypeScript 将此列表扩展为更多的内容,例如 `any` (允许任何类型)、[`unknown`](/play#example/unknown-and-never) (确保使用此类型的人声明类型是什么)、 [`never`](/play#example/unknown-and-never) (这种类型不可能发生)和 `void` (返回 `undefined` 或没有返回值的函数)。 + +构建类型有两种语法: [接口和类型](/play/?e=83#example/types-vs-interfaces)。 你应该更喜欢 `interface`。当需要特定功能时使用 `type` 。 + +## 组合类型 + +使用 TypeScript,可以通过组合简单类型来创建复杂类型。有两种流行的方法可以做到这一点:联合和泛型。 + +### 联合 + +使用联合,可以声明类型可以是许多类型中的一种。例如,可以将 `boolean` 类型描述为 `true` 或 `false` : + +```ts twoslash +type MyBool = true | false; +``` + +_注意:_如果将鼠标悬停在上面的 `MyBool` 上,您将看到它被归类为 `boolean`。这是结构化类型系统的一个属性。下面有更加详细的信息。 + +联合类型的一个流行用法是描述 `string` 或者 `number` 的[字面量](/docs/handbook/2/everyday-types.html#literal-types)的合法值。 + +```ts twoslash +type WindowStates = "open" | "closed" | "minimized"; +type LockStates = "locked" | "unlocked"; +type PositiveOddNumbersUnderTen = 1 | 3 | 5 | 7 | 9; +``` + +联合也提供了一种处理不同类型的方法。例如,可能有一个函数处理 `array` 或者 `string`: + +```ts twoslash +function getLength(obj: string | string[]) { + return obj.length; +} +``` + +要了解变量的类型, 使用 `typeof`: + +| 类型 | 推断语句 | +| --------- | ---------------------------------- | +| string | `typeof s === "string"` | +| number | `typeof n === "number"` | +| boolean | `typeof b === "boolean"` | +| undefined | `typeof undefined === "undefined"` | +| function | `typeof f === "function"` | +| array | `Array.isArray(a)` | + +例如,你可以使函数根据传递的是字符串还是数组返回不同的值: + + +```ts twoslash +function wrapInArray(obj: string | string[]) { + if (typeof obj === "string") { + return [obj]; +// ^? + } + return obj; +} +``` + +### 泛型 + +泛型为类型提供变量。一个常见的例子是数组。没有泛型的数组可以包含任何内容。带有泛型的数组可以描述数组包含的值。 + +```ts +type StringArray = Array; +type NumberArray = Array; +type ObjectWithNameArray = Array<{ name: string }>; +``` + +你可以声明自己使用泛型的类型: + +```ts twoslash +// @errors: 2345 +interface Backpack { + add: (obj: Type) => void; + get: () => Type; +} + +// 这一行是一个简写,可以告诉 TypeScript 有一个常量,叫做`backpack`,并且不用担心它是从哪 +// 里来的。 +declare const backpack: Backpack; + +// 对象是一个字符串,因为我们在上面声明了它作为 Backpack 的变量部分。 +const object = backpack.get(); + +// 因为 backpack 变量是一个字符串,不能将数字传递给 add 函数。 +backpack.add(23); +``` + +## 结构化的类型系统(structural type system) + +TypeScript 的一个核心原则是类型检查基于对象的属性和行为(type checking focuses on the _shape_ that values have)。这有时被叫做“鸭子类型”或“结构类型”(structural typing)。 + +在结构化的类型系统当中,如果两个对象具有相同的结构,则认为它们是相同类型的。 + +```ts twoslash +interface Point { + x: number; + y: number; +} + +function logPoint(p: Point) { + console.log(`${p.x}, ${p.y}`); +} + +// 打印 "12, 26" +const point = { x: 12, y: 26 }; +logPoint(point); +``` + + `point` 变量从未声明为 `Point` 类型。 但是,在类型检查中,TypeScript 将 `point` 的结构与 `Point`的结构进行比较。它们的结构相同,所以代码通过了。 + +结构匹配只需要匹配对象字段的子集。 + +```ts twoslash +// @errors: 2345 +interface Point { + x: number; + y: number; +} + +function logPoint(p: Point) { + console.log(`${p.x}, ${p.y}`); +} +// ---cut--- +const point3 = { x: 12, y: 26, z: 89 }; +logPoint(point3); // 打印 "12, 26" + +const rect = { x: 33, y: 3, width: 30, height: 80 }; +logPoint(rect); // 打印 "33, 3" + +const color = { hex: "#187ABF" }; +logPoint(color); +``` + +类和对象确定结构的方式没有区别: + +```ts twoslash +// @errors: 2345 +interface Point { + x: number; + y: number; +} + +function logPoint(p: Point) { + console.log(`${p.x}, ${p.y}`); +} +// ---分割线--- +class VirtualPoint { + x: number; + y: number; + + constructor(x: number, y: number) { + this.x = x; + this.y = y; + } +} + +const newVPoint = new VirtualPoint(13, 56); +logPoint(newVPoint); // 打印 "13, 56" +``` + +如果对象或类具有所有必需的属性,则 TypeScript 将表示是它们匹配的,而不关注其实现细节。 + +## 下一步 + +这是对一般的 TypeScript 中使用的语法和工具的简要概述。参见: + +- 阅读完整手册[由始至终](/docs/handbook/intro.html) (30 分钟) +- 探索 [Playground 上的示例](/play#show-examples) + diff --git a/docs/documentation/zh/get-started/TS for the New Programmer.md b/docs/documentation/zh/get-started/TS for the New Programmer.md new file mode 100644 index 00000000..bc6c48a4 --- /dev/null +++ b/docs/documentation/zh/get-started/TS for the New Programmer.md @@ -0,0 +1,159 @@ +--- +title: 面向编程初学者的 TypeScript +short: 面向编程初学者的 TS +layout: docs +permalink: /zh/docs/handbook/typescript-from-scratch.html +oneline: 从零开始学习 TypeScript +--- + +恭喜你选择 TypeScript 作为第一门编程语言 —— 你已经做出了明智的决定! + +或许你已经听说 TypeScript 是 JavaScript 的“调味料”或“变体”。在现代编程语言中,TypeScript(TS)和 JavaScript(JS)之间的关系相当独特,因此进一步了解这种关系,将帮助你了解如何把 TypeScript 添加到 JavaScript 中。 + +## 什么是 JavaScript? 一段简史 + +JavaScript(也称为ECMAScript)诞生时是一种简单的浏览器脚本语言。当它被发明时,它被期望用于在网页中嵌入简短的代码片段。这些片段通常不超过几十行。因此,早期的 Web 浏览器执行此类代码的速度非常慢。但是,随着时间的推移,JS 变得越来越流行,并且 Web 开发者开始使用它来创造交互式体验。 + +Web 浏览器开发者通过优化执行引擎(动态编译)和扩展可以完成的功能(添加API)来应对 JS 日益增加的使用量,这反过来又使 Web 开发者更多地使用 JS。在现代网站上,你的浏览器经常运行超过数十万行代码的应用程序。这是“网络”的长期而渐进的发展,从一个简单的静态页面网络开始,逐渐演变成一个用于各种丰富 _应用程序_ 的平台。 + +不仅如此,JS已经变得足够流行,以至于可以在浏览器环境之外使用。例如用 node.js 实现 JS 服务器。JS “随处运行”的特性使其成为跨平台开发的颇具吸引力的选择。如今,有许多开发者 _只_ 使用 JavaScript 便可完成全栈编程! + +总之,我们有一种语言,起初专为快速使用而设计,后来发展为功能强大的工具,可以编写具有数百万行的应用程序。每种语言都有它的 _怪异之处_,令人感到古怪或者惊讶。JavaScript 略显简陋的开端使得这种怪异之处 _很多_。 一些例子: + + +- JavaScript 的等于运算符(`==`)会试图 _强制_ 值相等,导致一些意外行为: + + ```js + if ("" == 0) { + // 他们相等!但是为什么呢?? + } + if (1 < x < 3) { + // x是 *任何* 值都为真! + } + ``` + +- JavaScript 还允许访问不存在的属性: + + ```js + const obj = { width: 10, height: 15 }; + // 为什么是 NaN?拼写好难! + const area = obj.width * obj.heigth; + ``` + +大多数编程语言会在发生此类错误时抛出错误提示,有些会在编译期间(在任何代码运行之前)这样做。在编写小型程序时,这种诡异虽表现很烦人,但很容易管理。当编写具有成百上千行代码的应用程序时,这些源源不断的奇怪的错误将是一个严重的问题。 + +## TypeScript: 静态类型检查器 + +前面我们提到,一些语言根本不允许那些错误的程序运行。在不运行代码的情况下检测其中的错误称为 _静态检查_ 。根据被操作的值的种类来确定是什么错误和什么不是错误,这称为静态 _类型_ 检查。 + +TypeScript 在执行之前,基于 _值的类型_ 检查程序是否有错误。它是 _静态类型检查器_。例如,基于 `obj` 的 _类型_,TypeScript 在上面的最后一个示例中发现了一个错误: + +```ts twoslash +// @errors: 2551 +const obj = { width: 10, height: 15 }; +const area = obj.width * obj.heigth; +``` + +### JavaScript 的类型化超集 + +不过,TypeScript 与 JavaScript 是什么关系呢? + +#### 语法 + +TypeScript 是 JavaScript 的 _超集_ :因此 JS 语法是合法的 TS。语法是指我们编写文本以组成程序的方式。例如,这段代码有一个 _语法_ 错误,因为它缺少一个 `)`: + +```ts twoslash +// @errors: 1005 +let a = (4 +``` + +TypeScript 不会将任何 JavaScript 代码视为错误。这意味着你可以将任何有效的 JavaScript 代码放在 TypeScript 文件中,而不必担心它的确切编写方式。 + +#### 类型 + +但是,TypeScript 是一个 _类型化_ 的超集,意味着它添加了针对如何使用不同类型的值的规则。之前关于 `obj.heigth` 的错误不是 _语法_ 错误,而是以不正确的方式使用了某种值( _类型_ )。 + +再举一个例子,这段 JavaScript 代码可以在浏览器中运行,它 _会_ 打印一个值: + +```js +console.log(4 / []); +``` + +该语法合法的程序打印出 `Infinity` 。但是,TypeScript 认为将数字除以数组是无意义的操作,并且会报错: + +```ts twoslash +// @errors: 2363 +console.log(4 / []); +``` + +你可能 _真的_ 想将数字除以数组,也许只是想看看会发生什么,但是在大多数时候,这是编程错误。TypeScript 的类型检查器旨在允许正确的程序通过,同时仍然捕获尽可能多的常见错误。(稍后,我们将学习如何配置 TypeScript,从而控制检查代码的严格程度。) + +如果将某些代码从 JavaScript 文件移动到 TypeScript 文件,可能会出现 _类型错误_ ,具体取决于代码的编写方式。这些或许是代码真实存在的问题,或者 TypeScript 过于保守。在本指南中,我们将演示如何增添各种 TypeScript 语法来消除此类错误。 + +#### 运行时行为 + +TypeScript 保留了 JavaScript 的 _运行时行为_ 。例如,在JavaScript 中被零除的结果是 `Infinity`,而不是抛出运行时异常。原则上,TypeScript **绝不** 改变 JavaScript 代码的运行时行为。 + +这意味着,如果将代码从 JavaScript 迁移到 TypeScript ,即使 TypeScript 认为代码有类型错误,也可以 **保证** 以相同的方式运行。 + +保持与 JavaScript 运行时行为相同是 TypeScript 的基本承诺。因为这意味着你可以轻松地在两种语言之间转换,而不必担心一些细微差别可能会使程序停止工作。 + + + +#### 擦除类型 + +粗略地说,一旦 TypeScript 的编译器完成了检查代码的工作,它就会 _擦除_ 类型以生成最终的“已编译”代码。这意味着一旦您的代码被编译,生成的普通 JS 代码便没有类型信息。 + +这也意味着 TypeScript 绝不会根据它推断的类型更改程序的 _行为_ 。最重要的是,尽管您可能会在编译过程中看到类型错误,但类型系统自身与程序如何运行无关。 + +最后,TypeScript 不提供任何额外运行时库。你的程序会使用与 JavaScript 程序相同的标准库(或外部库)。因此你不需要学习其他专属于 TypeScript 的框架。 + + + +## 学习 JavaScript 和 TypeScript + +我们经常看到这样的问题:“我该学习 JavaScript 还是 TypeScript?”。 + +答案是,不学习 JavaScript,就无法学习 TypeScript!TypeScript 共用了 JavaScript 的语法和运行时行为。因此,对JavaScript 的任何了解都可以帮助你学习 TypeScript 。 + +程序员可以使用很多很多资源来学习 JavaScript 。如果你正在编写 TypeScript,_不应该_ 忽略这些资源。例如,带有 `javascript` 标签的 StackOverflow 问题大约比 `typescript` 标签的多20倍,但是 _所有_ `javascript`问题也适用于 TypeScript 。 + +如果你正在搜索“如何在 TypeScript 中对列表进行排序”之类的内容,请记住: **TypeScript 是带有编译时类型检查器的 JavaScript 运行时** 。在 TypeScript 中对列表进行排序的方式与在 JavaScript 中相同。如果你找到直接使用 TypeScript 的资源,那也很好,但解决运行时任务的日常问题时,不要局限地认为你需要特定于 TypeScript 的答案。 + +## 下一步 + +以下是 TypeScript 中常用语法和工具的简要介绍。在这里,你可以: + +- 学习一些 JavaScript 基础知识 ([Mozilla Web Docs 的 JavaScript 指南 ](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide) 是个不错的开始) +- 继续阅读 [JavaScript 程序员的 TypeScript](/docs/handbook/typescript-in-5-minutes.html) +- 阅读完整手册 [从头至尾](/docs/handbook/intro.html) (30m) +- 探索 [游乐场示例](/play#show-examples) + + + diff --git a/docs/documentation/zh/handbook-v2/Basics.md b/docs/documentation/zh/handbook-v2/Basics.md new file mode 100644 index 00000000..82780e77 --- /dev/null +++ b/docs/documentation/zh/handbook-v2/Basics.md @@ -0,0 +1,512 @@ +--- +title: 基础 +layout: docs +permalink: /zh/docs/handbook/2/basic-types.html +oneline: "学习 TypeScript 的第一步:基本类型。" +preamble: > +

欢迎来到手册的第一页。如果这是你第一次接触到 TypeScript —— 你可能需要先阅读一下'入门'指南

+--- + +JavaScript 中的每个值会随着我们执行不同的操作表现出一系列的行为。 + +这听起来很抽象,看下面的例子,考虑一下针对变量 `message` 可能执行的操作。 + +```js +// 访问 message 的 toLowerCase 方法并调用它 +message.toLowerCase(); + +// 调用 message 函数 +message(); +``` + +如果我们拆分这个过程,那么第一行代码就是访问了 `message` 的 `toLowerCase` 方法并调用它; + +第二行代码则尝试直接调用 `message` 函数。 + +不过让我们假设一下,我们并不知道 `message` 的值 —— 这是很常见的一种情况,仅从上面的代码中我们无法确切得知最终的结果。 +每个操作的结果完全取决于 `message` 的初始值。 + +- `message` 是否可以调用? +- 它有 `toLowerCase` 属性吗? +- 如果有这个属性,那么 `toLowerCase` 可以调用吗? +- 如果 `message` 以及它的属性都是可以调用的,那么分别返回什么? + +在编写 JavaScript 代码的时候,这些问题的答案经常需要我们自己记在脑子里,而且我们必须得祈祷自己处理好了所有细节。 + +假设 `message` 是这样定义的: + +```js +const message = "Hello World!"; +``` + +你可能很容易猜到,如果执行 `message.toLowerCase()`,我们将会得到一个所有字母都是小写的字符串。 + +如果执行第二行代码呢? + +熟悉 JavaScript 的你肯定猜到了,这会抛出一个异常: + +```txt +TypeError: message is not a function +``` + +如果可以避免这样的错误就好了。 + +当我们执行代码的时候,JavaScript 运行时会计算出值的**类型** —— 这种类型有什么行为和功能,从而决定采取什么措施。 + +这就是上面的代码会抛出 `TypeError` 的原因 —— 它表明字符串 `"Hello World!"` 无法作为函数被调用。 + +对于诸如 `string` 或者 `number` 这样的原始类型,我们可以通过 `typeof` 操作符在运行时计算出它们的类型。 + +但对于像函数这样的类型,并没有对应的运行时机制去计算类型。 + +举个例子,看下面的函数: + +```js +function fn(x) { + return x.flip(); +} +``` + +从代码可以**看出**,仅当存在一个带有 `flip` 属性的对象时,这个函数才可以正常运行,但 JavaScript 无法在代码执行时以一种我们可以检查的方式传递这个信息。 + +要让纯 JavaScript 告诉我们 `fn` 在给定特定参数的时候会做什么事,唯一的方法就是实际调用 `fn` 函数。 + +这样的行为使得我们很难在代码执行前进行相关的预测,也意味着我们在编写代码的时候,很难搞清楚代码会做什么事。 + +从这个角度看,所谓的**类型**其实就是描述了什么值可以安全传递给 `fn`,什么值会引起报错。 + +JavaScript 只提供了动态类型 —— 执行代码,然后才能知道会发生什么事。 + +那么不妨采用一种替代方案,使用一个静态的类型系统,在代码实际执行前预测代码的行为。 + +## 静态类型检查 + +还记得之前我们将字符串作为函数调用时,抛出的 `TypeError` 错误吗? + +**很多人**不希望在执行代码时看到任何错误 —— 毕竟这些都是 bug! + +当我们编写新代码的时候,我们也会尽量避免引入新的 bug。 + +如果我们只是添加了一点代码,保存文件,重新运行代码,然后马上看到报错,那么我们或许可以快速定位到问题 —— 但这种情况毕竟只是少数。 + +我们可能没有全面、彻底地进行测试,以至于没有发现一些潜在错误! + +或者,如果我们幸运地发现了这个错误,我们可能最终会进行大规模的重构,并添加许多不同的代码。 + +理想的方案应该是,我们有一个工具可以在代码执行前找出 bug。 + +而这正是像 TypeScript 这样的静态类型检查器所做的事情。 + +**静态类型系统**描述了程序运行时值的结构和行为。 + +像 TypeScript 这样的静态类型检查器会利用类型系统提供的信息,并在事态发展不对劲的时候告知我们。 + +```ts twoslash +// @errors: 2349 +const message = "hello!"; + +message(); +``` + +用 TypeScript 运行上一个例子,它会在我们执行代码之前首先抛出一个错误。 + +## 非异常失败 + +目前为止,我们讨论的都是运行时错误 —— JavaScript 运行时告诉我们,它觉得某个地方有异常。 + +这些异常之所以能够抛出,是因为 [ECMAScript 规范](https://tc39.github.io/ecma262/) 明确规定了针对异常应该表现的行为。 + +举个例子,规范指出,试图调用无法调用的东西应该抛出一个错误。 + +也许这听上去像是“显而易见的行为”,并且你会觉得,访问对象上不存在的属性时,也会抛出一个错误。 + +但恰恰相反,JavaScript 的表现和我们的预想不同,它返回的是值 `undefined`。 + +```js +const user = { + name: 'Daniel', + age: 26, +}; +user.location; // 返回 undefined +``` + +最终,我们需要一个静态类型系统来告诉我们,哪些代码在这个系统中被标记为错误的代码 —— 即使它是不会马上引起错误的“有效” JavaScript 代码。 + +在 TypeScript 中,下面的代码会抛出一个错误,指出 `location` 没有定义: + +```ts twoslash +// @errors: 2339 +const user = { + name: "Daniel", + age: 26, +}; + +user.location; +``` + +虽然有时候这意味着你需要在表达的内容上进行权衡,但我们的目的是为了找到程序中更多合法的 bug。 + +而 TypeScript 也的确可以捕获到**很多**合法的 bug: + +举个例子,拼写错误: + +```ts twoslash +// @noErrors +const announcement = "Hello World!"; + +// 你需要花多久才能注意到拼写错误? +announcement.toLocaleLowercase(); +announcement.toLocalLowerCase(); + +// 实际上正确的拼写是这样的…… +announcement.toLocaleLowerCase(); +``` + +未调用的函数: + +```ts twoslash +// @noUnusedLocals +// @errors: 2365 +function flipCoin() { + // 应该是 Math.random() + return Math.random < 0.5; +} +``` + +或者是基本的逻辑错误: + +```ts twoslash +// @errors: 2367 +const value = Math.random() < 0.5 ? "a" : "b"; +if (value !== "a") { + // ... +} else if (value === "b") { +// 永远无法到达这个分支 +} +``` + +## 类型工具 + +TypeScript 可以在我们的代码出现错误时捕获 bug。 + +这很好,但更关键的是,它**也**能够在一开始就防止我们的代码出现错误。 + +类型检查器可以通过获取的信息检查我们是否正在访问变量或者其它属性上的正确属性。 + +一旦它获取到了这些信息,它也能够提示你可能想要访问的属性。 + +这意味着 TypeScript 也能用于编辑代码。我们在编辑器中输入的时候,核心的类型检查器能够提供报错信息和代码补全。 + +人们经常会谈到 TypeScript 在工具层面的作用,这就是一个典型的例子。 + + + +```ts twoslash +// @noErrors +// @esModuleInterop +import express from "express"; +const app = express(); + +app.get("/", function (req, res) { + res.sen +// ^| +}); + +app.listen(3000); +``` + +TypeScript 在工具层面的作用非常强大,远不止拼写时进行代码补全和错误信息提示。 + +支持 TypeScript 的编辑器可以通过“快速修复”功能自动修复错误,重构产生易组织的代码。同时,它还具备有效的导航功能,能够让我们跳转到某个变量定义的地方,或者找到对于给定变量的所有引用。 + +所有这些功能都建立在类型检查器上,并且是跨平台的,因此[你最喜欢的编辑器很可能也支持了 TypeScript](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Editor-Support)。 + +## TypeScript 编译器 —— tsc + +我们一直在讨论类型检查器,但目前为止还没上手使用过。 + +是时候和我们的新朋友 —— TypeScript 编译器 `tsc` 打交道了。 + +首先,通过 npm 进行安装。 + +```bash +npm install -g typescript +``` + +> 这将全局安装 TypeScript 的编译器 `tsc`。如果你更倾向于安装在本地的 node_modules 文件夹中,那你可能需要借助 npx 或者类似的工具才能便捷地运行 tsc 指令。 + +现在,我们新建一个空文件夹,尝试编写第一个 TypeScript 程序:`hello.ts` : + +```ts twoslash +// 和世界打个招呼 +console.log('Hello world!'); +``` + +注意这行代码没有任何多余的修饰,它看起来就和使用 JavaScript 编写的 “hello world” 程序一模一样。 + +现在,让我们运行 `typescript` 安装包自带的 `tsc` 指令进行类型检查。 + +```sh +tsc hello.ts +``` + +看! + +等等,“看”**什么**呢? + +我们运行了 `tsc` 指令,但什么事情也没有发生! + +是的,毕竟这行代码没有类型错误,所以控制台中当然看不到报错信息的输出。 + +不过再检查一下 —— 我们其实得到了一个输出**文件**。 + +如果我们查看当前目录,会发现除了 `hello.ts` 文件外还有一个 `hello.js` 文件。 + +而 `hello.js` 文件是 `tsc` **编译**或者**转换** `hello.ts` 文件之后输出的纯 JavaScript 文件。 + +如果检查 `hello.js` 文件的内容,我们可以看到 TypeScript 编译器处理完 `.ts` 文件后产出的内容: + +```js +// 和世界打个招呼 +console.log('Hello world!'); +``` + +在这个例子中,TypeScript 几乎没有需要转译的内容,所以转译前后的代码看起来一模一样。 + +编译器总是试图产出清晰可读的代码,这些代码看起来就像正常的开发者编写的一样。 + +虽然这不是一件容易的事情,但 TypeScript 始终保持缩进,关注跨行的代码,并且会尝试保留注释。 + +如果我们刻意引入了一个类型检查错误呢? + +我们重写一下 `hello.ts` : + +```ts twoslash +// @noErrors +// This is an industrial-grade general-purpose greeter function: +function greet(person, date) { + console.log(`Hello ${person}, today is ${date}!`); +} + +greet("Brendan"); +``` + +如果我们再次执行 `tsc hello.ts`,那么会注意到命令行抛出了一个错误! + +```txt +Expected 2 arguments, but got 1. +``` + +TypeScript 告诉我们,我们少传了一个参数给 `greet` 函数 —— 本来应该是要传入参数的。 + +目前为止,我们编写的仍然是标准的 JavaScript 代码,但类型检查依然可以发现我们代码中的问题。 + +感谢 TypeScript! + +## 报错时仍产出文件 + +有一件事你可能没有注意到,在上面的例子中,我们的 `hello.js` 文件再次发生了改动。 + +如果我们打开这个文件,会发现内容和输入的文件内容是一样的。 + +这可能有点出乎意料,毕竟 `tsc` 刚才报错了。但这种结果其实和 TypeScript 的核心原则有关:大多数时候,**你**比 TypeScript 更了解代码。 + +再次重申,对代码进行类型检查,会限制可以运行的程序的种类,因此类型检查器会进行权衡,以确定哪些代码是可以被接受的。 + +大多数时候,这样没什么问题,但有的时候,这些检查会对我们造成阻碍。 + +举个例子,想象你现在正把 JavaScript 代码迁移到 TypeScript 代码,并产生了很多类型检查错误。 + +最后,你不得不花费时间解决类型检查器抛出的错误,但问题在于,原始的 JavaScript 代码本身就是可以运行的!为什么把它们转换为 TypeScript 代码之后,反而就不能运行了呢? + +所以 TypeScript 并不会对你造成阻碍。 + +当然,随着时间的推移,你可能希望对错误采取更具防御性的措施,同时也让 TypeScript 采取更加严格的行为。 + +在这种情况下,你可以开启 [noEmitOnError](https://www.typescriptlang.org/tsconfig#noEmitOnError) 编译选项。 + +尝试修改你的 `hello.ts` 文件,并使用参数去运行 `tsc` 指令: + +```sh +tsc --noEmitOnError hello.ts +``` + +现在你会发现,`hello.js` 没有再发生改动了。 + +## 显式类型 + +目前为止,我们还没有告诉 TypeScript `person` 和 `date` 是什么。 + +我们修改一下代码,告诉 TypeScript `person` 是一个 `string` ,`data` 则应该是一个 `Date` 对象。 + +我们也会通过 `date` 去调用 `toDateString` 方法。 + +```ts twoslash +function greet(person: string, date: Date) { + console.log(`Hello ${person}, today is ${date.toDateString()}!`); +} +``` + +我们所做的事情,是给 `person` 和 `date` 添加**类型注解**,描述 `greet` 调用的时候应该接受什么类型的参数。 + +你可以将这个签名解读为“`greet` 接受 `string` 类型的 `person`,以及 `Date` 类型的 `date`”。 + +有了类型注解之后,TypeScript 就能告诉我们,哪些情况下对于 `greet` 的调用可能是不正确的。 + +比如…… + +```ts twoslash +// @errors: 2345 +function greet(person: string, date: Date) { + console.log(`Hello ${person}, today is ${date.toDateString()}!`); +} + +greet("Maddison", Date()); +``` + +哈? + +TypeScript 报错提示第二个参数有问题,但这是为什么呢? + +你可能会有点惊讶,因为在 JavaScript 中直接调用 `Date()` 返回的是 `string`。 + +另一方面,通过 `new Date()` 去构造一个 `Date`,则可以如预期那样返回一个 `Date` 对象。 + +不管怎样,我们可以快速修复这个错误: + +```ts twoslash {4} +function greet(person: string, date: Date) { + console.log(`Hello ${person}, today is ${date.toDateString()}!`); +} + +greet("Maddison", new Date()); +``` + +记住,我们并不总是需要显式地进行类型注解。 + +在很多情况下,即使省略了类型注解,TypeScript 也可以为我们**推断出**(或者“搞清楚”)类型。 + +```ts twoslash +let msg = "hello there!"; +// ^? +``` + +即使我们没有告诉 TypeScript `msg` 的类型是 `string`,它自己也能够搞清楚。 + +这是一个特性,在类型系统能够正确地进行类型推断的时候,最好不要手动添加类型注解了。 + +> 注意:代码信息会在上面的代码示例中展示出来。如果将鼠标放到变量上面,那么编辑器也会有相同的提示。 + +## 擦除类型 + +我们看一下,通过 `tsc` 将上面的 `greet` 函数编译成 JavaScript 后会发生什么事: + +```ts twoslash +// @showEmit +// @target: es5 +function greet(person: string, date: Date) { + console.log(`Hello ${person}, today is ${date.toDateString()}!`); +} + +greet("Maddison", new Date()); +``` + +注意到有两个变化: + +1. 我们的 `person` 和 `date` 参数的类型注解不见了。 +2. 我们的“模板字符串” —— 使用反引号(`` ` ``)包裹的字符串 —— 变成了通过 `+` 拼接的普通字符串。 + +稍后再解释第二点,我们先来看第一个变化。 + +类型注解并不属于 JavaScript(或者专业上所说的 ECMAScript)的内容,所以没有任何浏览器或者运行时能够直接执行不经处理的 TypeScript 代码。 + +这也是为什么 TypeScript 首先需要一个编译器 —— 它需要经过编译,才能去除或者转换 TypeScript 独有的代码,从而让这些代码可以在浏览器上运行。 + +大多数 TypeScript 独有的代码都会被擦除,在这个例子中,可以看到类型注解的代码完全被擦除了。 + +> **记住:**类型注解永远不会改变你的程序在运行时的行为 + +## 降级 + +上面的另一个变化,就是我们的模板字符串从: + +```js +`Hello ${person}, today is ${date.toDateString()}!`; +``` + +被重写为: + +```js +"Hello " + person + ", today is " + date.toDateString() + "!"; +``` + +为什么会这样子呢? + +模板字符串是 ECMAScript 2015(或者 ECMAScript6、ES2015、ES6 等)引入的新特性。 + +TypeScript 可以将高版本 ECMAScript 的代码重写为类似 ECMAScript3 或者 ECMAScript5 (也就是 ES3 或者 ES5)这样较低版本的代码。 + +类似这样将更新或者“更高”版本的 ECMAScript 向下降级为更旧或者“更低”版本的代码,就是所谓的**降级**。 + +默认情况下,TypeScript 会转化为 ES3 代码,这是一个非常旧的 ECMAScript 版本。我们可以使用 [target](https://www.typescriptlang.org/tsconfig#target) 选项将代码往较新的 ECMAScript 版本转换。 + +通过使用 `--target es2015` 参数进行编译,我们可以得到 ECMAScript2015 版本的目标代码,这意味着这些代码能够在支持 ECMAScript2015 的环境中执行。 + +因此,运行 `tsc --target es2015 hello.ts` 之后,我们会得到如下代码: + +```js +function greet(person, date) { + console.log(`Hello ${person}, today is ${date.toDateString()}!`); +} +greet("Maddison", new Date()); +``` + +> 虽然默认的目标代码采用的是 ES3 语法,但现在浏览器大多数都已经支持 ES2015 了。 +> +> 所以,大多数开发者可以安全地指定目标代码采用 ES2015 或者是更高的 ES 版本,除非你需要着重兼容某些古老的浏览器。 + +## 严格性 + +不同的用户会由于不同的理由去选择使用 TypeScript 的类型检查器。 + +一些用户寻求的是一种更加松散、可选的开发体验,他们希望类型检查仅作用于部分代码,同时还可享受 TypeScript 提供的功能。 + +这也是 TypeScript 默认提供的开发体验,类型是可选的,推断会使用最松散的类型,对于潜在的 `null/undefined` 类型的值也不会进行检查。 + +就像 `tsc` 在编译报错的情况下仍然能够正常产出文件一样,这些默认的配置会确保不对你的开发过程造成阻碍。 + +如果你正在迁移现有的 JavaScript 代码,那么这样的配置可能刚好适合。 + +另一方面,大多数的用户更希望 TypeScript 可以快速地、尽可能多地检查代码,这也是这门语言提供了严格性设置的原因。 + +这些严格性设置将静态的类型检查从一种切换开关的模式(对于你的代码,要么全部进行检查,要么完全不检查)转换为接近于刻度盘那样的模式。 + +你越是调节它,TypeScript 就会为你检查越多东西。 + +这可能需要额外的工作,但从长远来看,这是值得的,它可以带来更彻底的检查以及更精细的工具。 + +如果可能,新的代码库应该始终启用这些严格性配置。 + +TypeScript 有几个和类型检查相关的严格性设置,它们可以随时打开或关闭,如若没有特殊说明,我们文档中的例子都是在开启所有严格性设置的情况下执行的。 + +CLI 中的 [strict](/tsconfig#strict) 配置项,或者 [`tsconfig.json`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) 中的 `"strict: true"` 配置项,可以一次性开启全部严格性设置。但我们也可以单独开启或者关闭某个设置。 + +在所有这些设置中,尤其需要关注的是 [`noImplicitAny`](/tsconfig#noImplicitAny) 和 [`strictNullChecks`](/tsconfig#strictNullChecks)。 + +## `noImplicitAny` + +回想一下,在前面的某些例子中,TypeScript 没有为我们进行类型推断,这时候变量会采用最宽泛的类型:`any`。这并不是一件最糟糕的事情 —— 毕竟,使用 `any` 类型基本就和纯 JavaScript 一样了。 + +但是,使用 `any` 通常会和使用 TypeScript 的目的相违背。 + +你的程序使用越多的类型,那么在验证和工具上你的收益就越多,这意味着在编码的时候你会遇到越少的 bug。 + +启用 [noImplicitAny](https://www.typescriptlang.org/tsconfig#noImplicitAny) 配置项,在遇到被隐式推断为 `any` 类型的变量时就会抛出一个错误。 + +## `strictNullChecks` + +默认情况下,`null` 和 `undefined` 可以被赋值给其它任意类型。 + +这会让你的编码更加容易,但世界上无数多的 bug 正是由于忘记处理 `null` 和 `undefined` 导致的 —— 有时候它甚至会带来[数十亿美元的损失](https://www.youtube.com/watch?v=ybrQvs4x0Ps)! + +[strictNullChecks](https://www.typescriptlang.org/tsconfig#strictNullChecks) 配置项让处理 `null` 和 `undefined` 的过程更加明显,让我们**不用**担心自己是否**忘记**处理 `null` 和 `undefined`。 diff --git a/docs/documentation/zh/handbook-v2/Everyday Types.md b/docs/documentation/zh/handbook-v2/Everyday Types.md new file mode 100644 index 00000000..e715eb91 --- /dev/null +++ b/docs/documentation/zh/handbook-v2/Everyday Types.md @@ -0,0 +1,712 @@ +--- +title: 常见类型 +layout: docs +permalink: /zh/docs/handbook/2/everyday-types.html +oneline: "The language primitives." +--- + +在本章中,我们将介绍一些在 JavaScript 代码中最常见的值的类型,并说明在 TypeScript 中描述这些类型相应的方法。 +这不是一个详尽的列表,后续章节将描述命名和使用其他类型的更多方法。 + +类型还可以出现在许多 _地方_ ,而不仅仅是类型注释。 +在我们了解类型本身的同时,我们还将了解在哪些地方可以引用这些类型来形成新的结构。 + +我们将首先回顾一下你在编写 JavaScript 或 TypeScript 代码时可能遇到的最基本和最常见的类型。 +这些将在稍后形成更复杂类型的核心构建块。 + +## 基本类型:`string`,`number`,和 `boolean` + +JavaScript has three very commonly used [primitives](https://developer.mozilla.org/en-US/docs/Glossary/Primitive): `string`, `number`, and `boolean`. +Each has a corresponding type in TypeScript. +As you might expect, these are the same names you'd see if you used the JavaScript `typeof` operator on a value of those types: + +- `string` represents string values like `"Hello, world"` +- `number` is for numbers like `42`. JavaScript does not have a special runtime value for integers, so there's no equivalent to `int` or `float` - everything is simply `number` +- `boolean` is for the two values `true` and `false` + +> The type names `String`, `Number`, and `Boolean` (starting with capital letters) are legal, but refer to some special built-in types that will very rarely appear in your code. _Always_ use `string`, `number`, or `boolean` for types. + +## Arrays + +To specify the type of an array like `[1, 2, 3]`, you can use the syntax `number[]`; this syntax works for any type (e.g. `string[]` is an array of strings, and so on). +You may also see this written as `Array`, which means the same thing. +We'll learn more about the syntax `T` when we cover _generics_. + +> Note that `[number]` is a different thing; refer to the section on _tuple types_. + +## `any` + +TypeScript also has a special type, `any`, that you can use whenever you don't want a particular value to cause typechecking errors. + +When a value is of type `any`, you can access any properties of it (which will in turn be of type `any`), call it like a function, assign it to (or from) a value of any type, or pretty much anything else that's syntactically legal: + +```ts twoslash +let obj: any = { x: 0 }; +// None of the following lines of code will throw compiler errors. +// Using `any` disables all further type checking, and it is assumed +// you know the environment better than TypeScript. +obj.foo(); +obj(); +obj.bar = 100; +obj = "hello"; +const n: number = obj; +``` + +The `any` type is useful when you don't want to write out a long type just to convince TypeScript that a particular line of code is okay. + +### `noImplicitAny` + +When you don't specify a type, and TypeScript can't infer it from context, the compiler will typically default to `any`. + +You usually want to avoid this, though, because `any` isn't type-checked. +Use the compiler flag [`noImplicitAny`](/tsconfig#noImplicitAny) to flag any implicit `any` as an error. + +## Type Annotations on Variables + +When you declare a variable using `const`, `var`, or `let`, you can optionally add a type annotation to explicitly specify the type of the variable: + +```ts twoslash +let myName: string = "Alice"; +// ^^^^^^^^ Type annotation +``` + +> TypeScript doesn't use "types on the left"-style declarations like `int x = 0;` +> Type annotations will always go _after_ the thing being typed. + +In most cases, though, this isn't needed. +Wherever possible, TypeScript tries to automatically _infer_ the types in your code. +For example, the type of a variable is inferred based on the type of its initializer: + +```ts twoslash +// No type annotation needed -- 'myName' inferred as type 'string' +let myName = "Alice"; +``` + +For the most part you don't need to explicitly learn the rules of inference. +If you're starting out, try using fewer type annotations than you think - you might be surprised how few you need for TypeScript to fully understand what's going on. + +## Functions + +Functions are the primary means of passing data around in JavaScript. +TypeScript allows you to specify the types of both the input and output values of functions. + +### Parameter Type Annotations + +When you declare a function, you can add type annotations after each parameter to declare what types of parameters the function accepts. +Parameter type annotations go after the parameter name: + +```ts twoslash +// Parameter type annotation +function greet(name: string) { + // ^^^^^^^^ + console.log("Hello, " + name.toUpperCase() + "!!"); +} +``` + +When a parameter has a type annotation, arguments to that function will be checked: + +```ts twoslash +// @errors: 2345 +declare function greet(name: string): void; +// ---cut--- +// Would be a runtime error if executed! +greet(42); +``` + +> Even if you don't have type annotations on your parameters, TypeScript will still check that you passed the right number of arguments. + +### Return Type Annotations + +You can also add return type annotations. +Return type annotations appear after the parameter list: + +```ts twoslash +function getFavoriteNumber(): number { + // ^^^^^^^^ + return 26; +} +``` + +Much like variable type annotations, you usually don't need a return type annotation because TypeScript will infer the function's return type based on its `return` statements. +The type annotation in the above example doesn't change anything. +Some codebases will explicitly specify a return type for documentation purposes, to prevent accidental changes, or just for personal preference. + +### Anonymous Functions + +Anonymous functions are a little bit different from function declarations. +When a function appears in a place where TypeScript can determine how it's going to be called, the parameters of that function are automatically given types. + +Here's an example: + +```ts twoslash +// @errors: 2551 +// No type annotations here, but TypeScript can spot the bug +const names = ["Alice", "Bob", "Eve"]; + +// Contextual typing for function +names.forEach(function (s) { + console.log(s.toUppercase()); +}); + +// Contextual typing also applies to arrow functions +names.forEach((s) => { + console.log(s.toUppercase()); +}); +``` + +Even though the parameter `s` didn't have a type annotation, TypeScript used the types of the `forEach` function, along with the inferred type of the array, to determine the type `s` will have. + +This process is called _contextual typing_ because the _context_ that the function occurred in informed what type it should have. +Similar to the inference rules, you don't need to explicitly learn how this happens, but understanding that it _does_ happen can help you notice when type annotations aren't needed. +Later, we'll see more examples of how the context that a value occurs in can affect its type. + +## Object Types + +Apart from primitives, the most common sort of type you'll encounter is an _object type_. +This refers to any JavaScript value with properties, which is almost all of them! +To define an object type, we simply list its properties and their types. + +For example, here's a function that takes a point-like object: + +```ts twoslash +// The parameter's type annotation is an object type +function printCoord(pt: { x: number; y: number }) { + // ^^^^^^^^^^^^^^^^^^^^^^^^ + console.log("The coordinate's x value is " + pt.x); + console.log("The coordinate's y value is " + pt.y); +} +printCoord({ x: 3, y: 7 }); +``` + +Here, we annotated the parameter with a type with two properties - `x` and `y` - which are both of type `number`. +You can use `,` or `;` to separate the properties, and the last separator is optional either way. + +The type part of each property is also optional. +If you don't specify a type, it will be assumed to be `any`. + +### Optional Properties + +Object types can also specify that some or all of their properties are _optional_. +To do this, add a `?` after the property name: + +```ts twoslash +function printName(obj: { first: string; last?: string }) { + // ... +} +// Both OK +printName({ first: "Bob" }); +printName({ first: "Alice", last: "Alisson" }); +``` + +In JavaScript, if you access a property that doesn't exist, you'll get the value `undefined` rather than a runtime error. +Because of this, when you _read_ from an optional property, you'll have to check for `undefined` before using it. + +```ts twoslash +// @errors: 2532 +function printName(obj: { first: string; last?: string }) { + // Error - might crash if 'obj.last' wasn't provided! + console.log(obj.last.toUpperCase()); + if (obj.last !== undefined) { + // OK + console.log(obj.last.toUpperCase()); + } + + // A safe alternative using modern JavaScript syntax: + console.log(obj.last?.toUpperCase()); +} +``` + +## Union Types + +TypeScript's type system allows you to build new types out of existing ones using a large variety of operators. +Now that we know how to write a few types, it's time to start _combining_ them in interesting ways. + +### Defining a Union Type + +The first way to combine types you might see is a _union_ type. +A union type is a type formed from two or more other types, representing values that may be _any one_ of those types. +We refer to each of these types as the union's _members_. + +Let's write a function that can operate on strings or numbers: + +```ts twoslash +// @errors: 2345 +function printId(id: number | string) { + console.log("Your ID is: " + id); +} +// OK +printId(101); +// OK +printId("202"); +// Error +printId({ myID: 22342 }); +``` + +### Working with Union Types + +It's easy to _provide_ a value matching a union type - simply provide a type matching any of the union's members. +If you _have_ a value of a union type, how do you work with it? + +TypeScript will only allow you to do things with the union if that thing is valid for _every_ member of the union. +For example, if you have the union `string | number`, you can't use methods that are only available on `string`: + +```ts twoslash +// @errors: 2339 +function printId(id: number | string) { + console.log(id.toUpperCase()); +} +``` + +The solution is to _narrow_ the union with code, the same as you would in JavaScript without type annotations. +_Narrowing_ occurs when TypeScript can deduce a more specific type for a value based on the structure of the code. + +For example, TypeScript knows that only a `string` value will have a `typeof` value `"string"`: + +```ts twoslash +function printId(id: number | string) { + if (typeof id === "string") { + // In this branch, id is of type 'string' + console.log(id.toUpperCase()); + } else { + // Here, id is of type 'number' + console.log(id); + } +} +``` + +Another example is to use a function like `Array.isArray`: + +```ts twoslash +function welcomePeople(x: string[] | string) { + if (Array.isArray(x)) { + // Here: 'x' is 'string[]' + console.log("Hello, " + x.join(" and ")); + } else { + // Here: 'x' is 'string' + console.log("Welcome lone traveler " + x); + } +} +``` + +Notice that in the `else` branch, we don't need to do anything special - if `x` wasn't a `string[]`, then it must have been a `string`. + +Sometimes you'll have a union where all the members have something in common. +For example, both arrays and strings have a `slice` method. +If every member in a union has a property in common, you can use that property without narrowing: + +```ts twoslash +// Return type is inferred as number[] | string +function getFirstThree(x: number[] | string) { + return x.slice(0, 3); +} +``` + +> It might be confusing that a _union_ of types appears to have the _intersection_ of those types' properties. +> This is not an accident - the name _union_ comes from type theory. +> The _union_ `number | string` is composed by taking the union _of the values_ from each type. +> Notice that given two sets with corresponding facts about each set, only the _intersection_ of those facts applies to the _union_ of the sets themselves. +> For example, if we had a room of tall people wearing hats, and another room of Spanish speakers wearing hats, after combining those rooms, the only thing we know about _every_ person is that they must be wearing a hat. + +## 类型别名 + +我们通过直接在类型注解中编写对象类型和联合类型来使用它们。 +这很方便,但是常常会想要多次使用同一个类型,并且通过一个名称引用它。 + +_类型别名_ 正是如此 - 任意 _类型_ 的一个 _名称_ 。 +类型别名的语法是: + +```ts twoslash +type Point = { + x: number; + y: number; +}; + +// 与前面的示例完全相同 +function printCoord(pt: Point) { + console.log("The coordinate's x value is " + pt.x); + console.log("The coordinate's y value is " + pt.y); +} + +printCoord({ x: 100, y: 100 }); +``` + +实际上,不只是对象类型,你可以使用类型别名为任何类型命名。 +例如,类型别名可以命名联合类型: + +```ts twoslash +type ID = number | string; +``` + +请注意,别名 _只是_ 别名 - 你不能使用类型别名创建同一类型的不同“版本”。 +当你使用别名时,它与您编写的别名类型完全一样。 +换句话说,这段代码 _看起来_ 可能是非法的,但是对于 TypeScript 来说是正确的,因为这两种类型都是同一类型的别名: + +```ts twoslash +declare function getInput(): string; +declare function sanitize(str: string): string; +// ---分割--- +type UserInputSanitizedString = string; + +function sanitizeInput(str: string): UserInputSanitizedString { + return sanitize(str); +} + +// 创建一个经过清理的输入框 +let userInput = sanitizeInput(getInput()); + +// 仍然可以使用字符串重新赋值 +userInput = "new input"; +``` + +## 接口 + +_接口声明_ 是命名对象类型的另一种方式: + +```ts twoslash +interface Point { + x: number; + y: number; +} + +function printCoord(pt: Point) { + console.log("The coordinate's x value is " + pt.x); + console.log("The coordinate's y value is " + pt.y); +} + +printCoord({ x: 100, y: 100 }); +``` + +就像我们上面使用类型别名时一样,这个示例的工作方式就像我们使用了匿名对象类型一样。 +TypeScript 只关心我们传递给 `printCoord` 的值的结构 - 它只关心它是否具有预期的属性。 +只关心类型的结构和功能,这就是为什么我们说 TypeScript 是一个 _结构化类型_ 的类型系统。 + +### 类型别名和接口之间的区别 + +类型别名和接口非常相似,在大多数情况下你可以在它们之间自由选择。 +几乎所有的 `interface` 功能都可以在 `type` 中使用,关键区别在于不能重新开放类型以添加新的属性,而接口始终是可扩展的。 + + + + + + + + + + + + + + + + +
InterfaceType
+

扩展接口

+
+interface Animal {
+  name: string
+}
+interface Bear extends Animal { + honey: boolean +}
+const bear = getBear() +bear.name +bear.honey +
+
+

通过 "&" 扩展类型

+
+type Animal = {
+  name: string
+}
+type Bear = Animal & { + honey: Boolean +}
+const bear = getBear(); +bear.name; +bear.honey; +
+
+

向现有接口添加新字段

+
+interface Window {
+  title: string
+}
+interface Window { + ts: TypeScriptAPI +}
+const src = 'const a = "Hello World"'; +window.ts.transpileModule(src, {}); +
+
+

类型创建后不能更改

+
+type Window = {
+  title: string
+}
+type Window = { + ts: TypeScriptAPI +}
+ // Error: Duplicate identifier 'Window'.
+
+
+ +在后面的章节中你会学到更多关于这些概念的知识,所以如果你没有立即理解这些知识,请不要担心。 + +- 在 TypeScript 4.2 之前,类型别名命名 [_可能_ 会出现在错误消息中](/play?#code/PTAEGEHsFsAcEsA2BTATqNrLusgzngIYDm+oA7koqIYuYQJ56gCueyoAUCKAC4AWHAHaFcoSADMaQ0PCG80EwgGNkALk6c5C1EtWgAsqOi1QAb06groEbjWg8vVHOKcAvpokshy3vEgyyMr8kEbQJogAFND2YREAlOaW1soBeJAoAHSIkMTRmbbI8e6aPMiZxJmgACqCGKhY6ABGyDnkFFQ0dIzMbBwCwqIccabcYLyQoKjIEmh8kwN8DLAc5PzwwbLMyAAeK77IACYaQSEjUWZWhfYAjABMAMwALA+gbsVjoADqgjKESytQPxCHghAByXigYgBfr8LAsYj8aQMUASbDQcRSExCeCwFiIQh+AKfAYyBiQFgOPyIaikSGLQo0Zj-aazaY+dSaXjLDgAGXgAC9CKhDqAALxJaw2Ib2RzOISuDycLw+ImBYKQflCkWRRD2LXCw6JCxS1JCdJZHJ5RAFIbFJU8ADKC3WzEcnVZaGYE1ABpFnFOmsFhsil2uoHuzwArO9SmAAEIsSFrZB-GgAjjA5gtVN8VCEc1o1C4Q4AGlR2AwO1EsBQoAAbvB-gJ4HhPgB5aDwem-Ph1TCV3AEEirTp4ELtRbTPD4vwKjOfAuioSQHuDXBcnmgACC+eCONFEs73YAPGGZVT5cRyyhiHh7AAON7lsG3vBggB8XGV3l8-nVISOgghxoLq9i7io-AHsayRWGaFrlFauq2rg9qaIGQHwCBqChtKdgRo8TxRjeyB3o+7xAA),有时代替等效的匿名类型(可能需要也可能不需要)。接口在错误消息中将始终被命名。 +- 类型别名不能参与 [声明合并,但接口可以](/play?#code/PTAEEEDtQS0gXApgJwGYEMDGjSfdAIx2UQFoB7AB0UkQBMAoEUfO0Wgd1ADd0AbAK6IAzizp16ALgYM4SNFhwBZdAFtV-UAG8GoPaADmNAcMmhh8ZHAMMAvjLkoM2UCvWad+0ARL0A-GYWVpA29gyY5JAWLJAwGnxmbvGgALzauvpGkCZmAEQAjABMAMwALLkANBl6zABi6DB8okR4Jjg+iPSgABboovDk3jjo5pbW1d6+dGb5djLwAJ7UoABKiJTwjThpnpnGpqPBoTLMAJrkArj4kOTwYmycPOhW6AR8IrDQ8N04wmo4HHQCwYi2Waw2W1S6S8HX8gTGITsQA)。 +- 接口只能用于 [声明对象的形状,不能重命名基本类型](/play?#code/PTAEAkFMCdIcgM6gC4HcD2pIA8CGBbABwBtIl0AzUAKBFAFcEBLAOwHMUBPQs0XFgCahWyGBVwBjMrTDJMAshOhMARpD4tQ6FQCtIE5DWoixk9QEEWAeV37kARlABvaqDegAbrmL1IALlAEZGV2agBfampkbgtrWwMAJlAAXmdXdy8ff0Dg1jZwyLoAVWZ2Lh5QVHUJflAlSFxROsY5fFAWAmk6CnRoLGwmILzQQmV8JmQmDzI-SOiKgGV+CaYAL0gBBdyy1KCQ-Pn1AFFplgA5enw1PtSWS+vCsAAVAAtB4QQWOEMKBuYVUiVCYvYQsUTQcRSBDGMGmKSgAAa-VEgiQe2GLgKQA). +- 接口名称将 [_始终_ 以其原始形式出现](/play?#code/PTAEGEHsFsAcEsA2BTATqNrLusgzngIYDm+oA7koqIYuYQJ56gCueyoAUCKAC4AWHAHaFcoSADMaQ0PCG80EwgGNkALk6c5C1EtWgAsqOi1QAb06groEbjWg8vVHOKcAvpokshy3vEgyyMr8kEbQJogAFND2YREAlOaW1soBeJAoAHSIkMTRmbbI8e6aPMiZxJmgACqCGKhY6ABGyDnkFFQ0dIzMbBwCwqIccabcYLyQoKjIEmh8kwN8DLAc5PzwwbLMyAAeK77IACYaQSEjUWY2Q-YAjABMAMwALA+gbsVjNXW8yxySoAADaAA0CCaZbPh1XYqXgOIY0ZgmcK0AA0nyaLFhhGY8F4AHJmEJILCWsgZId4NNfIgGFdcIcUTVfgBlZTOWC8T7kAJ42G4eT+GS42QyRaYbCgXAEEguTzeXyCjDBSAAQSE8Ai0Xsl0K9kcziExDeiQs1lAqSE6SyOTy0AKQ2KHk4p1V6s1OuuoHuzwArMagA) 在错误消息中,但 _只有_ 在按名称使用时才会出现。 + +在大多数情况下,你可以根据个人喜好进行选择,TypeScript 会告诉你它是否需要其他类型的声明。如果您想要启发式方法,可以使用 `interface` 直到你需要使用 `type` 中的功能。 + +## Type Assertions + +Sometimes you will have information about the type of a value that TypeScript can't know about. + +For example, if you're using `document.getElementById`, TypeScript only knows that this will return _some_ kind of `HTMLElement`, but you might know that your page will always have an `HTMLCanvasElement` with a given ID. + +In this situation, you can use a _type assertion_ to specify a more specific type: + +```ts twoslash +const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement; +``` + +Like a type annotation, type assertions are removed by the compiler and won't affect the runtime behavior of your code. + +You can also use the angle-bracket syntax (except if the code is in a `.tsx` file), which is equivalent: + +```ts twoslash +const myCanvas = document.getElementById("main_canvas"); +``` + +> Reminder: Because type assertions are removed at compile-time, there is no runtime checking associated with a type assertion. +> There won't be an exception or `null` generated if the type assertion is wrong. + +TypeScript only allows type assertions which convert to a _more specific_ or _less specific_ version of a type. +This rule prevents "impossible" coercions like: + +```ts twoslash +// @errors: 2352 +const x = "hello" as number; +``` + +Sometimes this rule can be too conservative and will disallow more complex coercions that might be valid. +If this happens, you can use two assertions, first to `any` (or `unknown`, which we'll introduce later), then to the desired type: + +```ts twoslash +declare const expr: any; +type T = { a: 1; b: 2; c: 3 }; +// ---cut--- +const a = expr as any as T; +``` + +## Literal Types + +In addition to the general types `string` and `number`, we can refer to _specific_ strings and numbers in type positions. + +One way to think about this is to consider how JavaScript comes with different ways to declare a variable. Both `var` and `let` allow for changing what is held inside the variable, and `const` does not. This is reflected in how TypeScript creates types for literals. + +```ts twoslash +let changingString = "Hello World"; +changingString = "Olá Mundo"; +// Because `changingString` can represent any possible string, that +// is how TypeScript describes it in the type system +changingString; +// ^? + +const constantString = "Hello World"; +// Because `constantString` can only represent 1 possible string, it +// has a literal type representation +constantString; +// ^? +``` + +By themselves, literal types aren't very valuable: + +```ts twoslash +// @errors: 2322 +let x: "hello" = "hello"; +// OK +x = "hello"; +// ... +x = "howdy"; +``` + +It's not much use to have a variable that can only have one value! + +But by _combining_ literals into unions, you can express a much more useful concept - for example, functions that only accept a certain set of known values: + +```ts twoslash +// @errors: 2345 +function printText(s: string, alignment: "left" | "right" | "center") { + // ... +} +printText("Hello, world", "left"); +printText("G'day, mate", "centre"); +``` + +Numeric literal types work the same way: + +```ts twoslash +function compare(a: string, b: string): -1 | 0 | 1 { + return a === b ? 0 : a > b ? 1 : -1; +} +``` + +Of course, you can combine these with non-literal types: + +```ts twoslash +// @errors: 2345 +interface Options { + width: number; +} +function configure(x: Options | "auto") { + // ... +} +configure({ width: 100 }); +configure("auto"); +configure("automatic"); +``` + +There's one more kind of literal type: boolean literals. +There are only two boolean literal types, and as you might guess, they are the types `true` and `false`. +The type `boolean` itself is actually just an alias for the union `true | false`. + +### Literal Inference + +When you initialize a variable with an object, TypeScript assumes that the properties of that object might change values later. +For example, if you wrote code like this: + +```ts twoslash +declare const someCondition: boolean; +// ---cut--- +const obj = { counter: 0 }; +if (someCondition) { + obj.counter = 1; +} +``` + +TypeScript doesn't assume the assignment of `1` to a field which previously had `0` is an error. +Another way of saying this is that `obj.counter` must have the type `number`, not `0`, because types are used to determine both _reading_ and _writing_ behavior. + +The same applies to strings: + +```ts twoslash +// @errors: 2345 +declare function handleRequest(url: string, method: "GET" | "POST"): void; +// ---cut--- +const req = { url: "https://example.com", method: "GET" }; +handleRequest(req.url, req.method); +``` + +In the above example `req.method` is inferred to be `string`, not `"GET"`. Because code can be evaluated between the creation of `req` and the call of `handleRequest` which could assign a new string like `"GUESS"` to `req.method`, TypeScript considers this code to have an error. + +There are two ways to work around this. + +1. You can change the inference by adding a type assertion in either location: + + ```ts twoslash + declare function handleRequest(url: string, method: "GET" | "POST"): void; + // ---cut--- + // Change 1: + const req = { url: "https://example.com", method: "GET" as "GET" }; + // Change 2 + handleRequest(req.url, req.method as "GET"); + ``` + + Change 1 means "I intend for `req.method` to always have the _literal type_ `"GET"`", preventing the possible assignment of `"GUESS"` to that field after. + Change 2 means "I know for other reasons that `req.method` has the value `"GET"`". + +2. You can use `as const` to convert the entire object to be type literals: + + ```ts twoslash + declare function handleRequest(url: string, method: "GET" | "POST"): void; + // ---cut--- + const req = { url: "https://example.com", method: "GET" } as const; + handleRequest(req.url, req.method); + ``` + +The `as const` suffix acts like `const` but for the type system, ensuring that all properties are assigned the literal type instead of a more general version like `string` or `number`. + +## `null` and `undefined` + +JavaScript has two primitive values used to signal absent or uninitialized value: `null` and `undefined`. + +TypeScript has two corresponding _types_ by the same names. How these types behave depends on whether you have the `strictNullChecks` option on. + +### `strictNullChecks` off + +With `strictNullChecks` _off_, values that might be `null` or `undefined` can still be accessed normally, and the values `null` and `undefined` can be assigned to a property of any type. +This is similar to how languages without null checks (e.g. C#, Java) behave. +The lack of checking for these values tends to be a major source of bugs; we always recommend people turn `strictNullChecks` on if it's practical to do so in their codebase. + +### `strictNullChecks` on + +With `strictNullChecks` _on_, when a value is `null` or `undefined`, you will need to test for those values before using methods or properties on that value. +Just like checking for `undefined` before using an optional property, we can use _narrowing_ to check for values that might be `null`: + +```ts twoslash +function doSomething(x: string | null) { + if (x === null) { + // do nothing + } else { + console.log("Hello, " + x.toUpperCase()); + } +} +``` + +### Non-null Assertion Operator (Postfix `!`) + +TypeScript also has a special syntax for removing `null` and `undefined` from a type without doing any explicit checking. +Writing `!` after any expression is effectively a type assertion that the value isn't `null` or `undefined`: + +```ts twoslash +function liveDangerously(x?: number | null) { + // No error + console.log(x!.toFixed()); +} +``` + +Just like other type assertions, this doesn't change the runtime behavior of your code, so it's important to only use `!` when you know that the value _can't_ be `null` or `undefined`. + +## Enums + +Enums are a feature added to JavaScript by TypeScript which allows for describing a value which could be one of a set of possible named constants. Unlike most TypeScript features, this is _not_ a type-level addition to JavaScript but something added to the language and runtime. Because of this, it's a feature which you should know exists, but maybe hold off on using unless you are sure. You can read more about enums in the [Enum reference page](/docs/handbook/enums.html). + +## Less Common Primitives + +It's worth mentioning the rest of the primitives in JavaScript which are represented in the type system. +Though we will not go into depth here. + +##### `bigint` + +From ES2020 onwards, there is a primitive in JavaScript used for very large integers, `BigInt`: + +```ts twoslash +// @target: es2020 + +// Creating a bigint via the BigInt function +const oneHundred: bigint = BigInt(100); + +// Creating a BigInt via the literal syntax +const anotherHundred: bigint = 100n; +``` + +You can learn more about BigInt in [the TypeScript 3.2 release notes](/docs/handbook/release-notes/typescript-3-2.html#bigint). + +##### `symbol` + +There is a primitive in JavaScript used to create a globally unique reference via the function `Symbol()`: + +```ts twoslash +// @errors: 2367 +const firstName = Symbol("name"); +const secondName = Symbol("name"); + +if (firstName === secondName) { + // Can't ever happen +} +``` + +You can learn more about them in [Symbols reference page](/docs/handbook/symbols.html). diff --git a/docs/documentation/zh/handbook-v2/Type Manipulation/Conditional Types.md b/docs/documentation/zh/handbook-v2/Type Manipulation/Conditional Types.md new file mode 100644 index 00000000..abd3e634 --- /dev/null +++ b/docs/documentation/zh/handbook-v2/Type Manipulation/Conditional Types.md @@ -0,0 +1,275 @@ +--- +title: 条件类型 +layout: docs +permalink: /zh/docs/handbook/2/conditional-types.html +oneline: "Create types which act like if statements in the type system." +--- + +大多数有效程序的核心是,我们必须依据输入做出一些决定。 +JavaScript 程序也是如此,但是由于值可以很容易地被内省,这些决定也是基于输入的类型。 +_条件类型_ 有助于描述输入和输出类型之间的关系。 + +```ts twoslash +interface Animal { + live(): void; +} +interface Dog extends Animal { + woof(): void; +} + +type Example1 = Dog extends Animal ? number : string; +// ^? + +type Example2 = RegExp extends Animal ? number : string; +// ^? +``` + +条件类型看起来有点像 JavaScript 中的条件表达式(`条件 ? true 表达式 : false 表达式`): + +```ts twoslash +type SomeType = any; +type OtherType = any; +type TrueType = any; +type FalseType = any; +type Stuff = + // ---cut--- + SomeType extends OtherType ? TrueType : FalseType; +``` + +当 `extends` 左边的类型可以赋值给右边的类型时,你将获得第一个分支("true" 分支)中的类型;否则你将获得后一个分支("false" 分支)中的类型。 + +从上面的例子中,条件类型可能不会立即显得很有用 - 我们可以告诉自己是否 `Dog extends Animal` 并选择 `number` 或 `string`! +但是条件类型的威力来自于将它们与泛型一起使用。 + +让我们以下面的 `createLabel` 函数为例: + +```ts twoslash +interface IdLabel { + id: number /* 一些字段 */; +} +interface NameLabel { + name: string /* 其它字段 */; +} + +function createLabel(id: number): IdLabel; +function createLabel(name: string): NameLabel; +function createLabel(nameOrId: string | number): IdLabel | NameLabel; +function createLabel(nameOrId: string | number): IdLabel | NameLabel { + throw "unimplemented"; +} +``` + +这些 createLabel 的重载描述了单个基于输入类型进行选择的 JavaScript 函数。注意以下几点: + +1. 如果一个库不得不在其 API 中一遍又一遍地做出相同的选择,这就变得很麻烦。 +2. 我们必须创建三个重载:一种用于我们 _确定_ 类型时的每种情况(一个用于 `string`,一个用于 `number`),一个用于最一般的情况(接受一个 `string | number`)。对于 `createLabel` 可以处理的每个新类型,重载的数量都会呈指数增长。 + +相反,我们可以将该逻辑转换为条件类型: + +```ts twoslash +interface IdLabel { + id: number /* 一些字段 */; +} +interface NameLabel { + name: string /* 其它字段 */; +} +// ---cut--- +type NameOrId = T extends number + ? IdLabel + : NameLabel; +``` + +然后,我们可以使用该条件类型将重载简化为没有重载的单个函数。 + +```ts twoslash +interface IdLabel { + id: number /* 一些字段 */; +} +interface NameLabel { + name: string /* 其它字段 */; +} +type NameOrId = T extends number + ? IdLabel + : NameLabel; +// ---cut--- +function createLabel(idOrName: T): NameOrId { + throw "unimplemented"; +} + +let a = createLabel("typescript"); +// ^? + +let b = createLabel(2.8); +// ^? + +let c = createLabel(Math.random() ? "hello" : 42); +// ^? +``` + +### 条件类型约束 + +通常,条件类型的检查将为我们提供一些新信息。 +就像使用类型守卫缩小范围可以给我们提供更具体的类型一样,条件类型的 true 分支将根据我们检查的类型进一步约束泛型。 + +让我们来看看下面的例子: + +```ts twoslash +// @errors: 2536 +type MessageOf = T["message"]; +``` + +在本例中,TypeScript 产生错误是因为不知道 `T` 有一个名为 `message` 的属性。 +我们可以约束 `T`,TypeScript 也不会再抱怨了: + +```ts twoslash +type MessageOf = T["message"]; + +interface Email { + message: string; +} + +interface Dog { + bark(): void; +} + +type EmailMessageContents = MessageOf; +// ^? +``` + +然而,如果我们希望 `MessageOf` 接受任何类型,并且在 `message` 属性不可用的情况下默认为 `never` 之类的类型,我们应该怎么做呢? +我们可以通过移出约束并引入条件类型来实现这一点: + +```ts twoslash +type MessageOf = T extends { message: unknown } ? T["message"] : never; + +interface Email { + message: string; +} + +interface Dog { + bark(): void; +} + +type EmailMessageContents = MessageOf; +// ^? + +type DogMessageContents = MessageOf; +// ^? +``` + +在 true 分支中,TypeScript 知道 `T` _将_ 有一个 `message` 属性。 + +作为另一个示例,我们还可以编写一个名为 `Flatten` 的类型,它将数组类型扁平为它们的元素类型,但在其他情况下不会处理它们: + +```ts twoslash +type Flatten = T extends any[] ? T[number] : T; + +// Extracts out the element type. +type Str = Flatten; +// ^? + +// Leaves the type alone. +type Num = Flatten; +// ^? +``` + +当 `Flatten` 被赋予数组类型时,它使用带 `number` 的索引访问来提取 `string[]` 的元素类型。 +否则,它只返回给定的类型。 + +### 在条件类型中推断 + +我们发现自己使用条件类型来应用约束,然后提取出类型。 +这最终成为一种非常常见的操作,条件类型使其变得更容易。 + +条件类型为我们提供了一种使用 `infer` 关键字从 true 分支中与之进行比较的类型中进行推断的方法。 +例如,我们可以在 `Flatten` 中推断元素类型,而不是使用索引访问类型“手动”提取它: + +```ts twoslash +type Flatten = Type extends Array ? Item : Type; +``` + +在这里,我们使用 `infer` 关键字以声明方式引入一个名为 `Item` 的新泛型类型变量,而不是指定如何在 true 分支中检索元素类型 `T`。 +这使我们不必考虑如何挖掘和探索我们感兴趣的类型的结构。 + +我们可以使用 `infer` 关键字编写一些有用的助手类型别名。 +例如,对于简单的情况,我们可以从函数类型中提取返回类型: + +```ts twoslash +type GetReturnType = Type extends (...args: never[]) => infer Return + ? Return + : never; + +type Num = GetReturnType<() => number>; +// ^? + +type Str = GetReturnType<(x: string) => string>; +// ^? + +type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]>; +// ^? +``` + +当从具有多个调用签名的类型(如重载函数的类型)进行推断时,将从 _最后一个_ 签名进行推断(这也许是最宽松的万能情况)。无法基于参数类型列表执行重载决议。 + +```ts twoslash +declare function stringOrNum(x: string): number; +declare function stringOrNum(x: number): string; +declare function stringOrNum(x: string | number): string | number; + +type T1 = ReturnType; +// ^? +``` + +## 分配条件类型 + +当传入的类型参数为联合类型时,他们会被 _分配类型_ 。 +以下面的例子为例: + +```ts twoslash +type ToArray = Type extends any ? Type[] : never; +``` + +如果我们将联合类型传入 `ToArray`,则条件类型将应用于该联合类型的每个成员。 + +```ts twoslash +type ToArray = Type extends any ? Type[] : never; + +type StrArrOrNumArr = ToArray; +// ^? +``` + +这里发生的情况是 `StrOrNumArray` 分布在以下位置: + +```ts twoslash +type StrArrOrNumArr = + // ---cut--- + string | number; +``` + +并在联合类型的每个成员类型上映射到有效的内容: + +```ts twoslash +type ToArray = Type extends any ? Type[] : never; +type StrArrOrNumArr = + // ---cut--- + ToArray | ToArray; +``` + +所以我们得到: + +```ts twoslash +type StrArrOrNumArr = + // ---cut--- + string[] | number[]; +``` + +通常,分布性是所需的行为。 +要避免这种行为,可以用方括号括起 `extends` 关键字的两边。 + +```ts twoslash +type ToArrayNonDist = [Type] extends [any] ? Type[] : never; + +// 'StrOrNumArr' 不再是一个联合类型 +type StrOrNumArr = ToArrayNonDist; +// ^? +``` diff --git a/docs/playground/ko/3-7/Types and Code Flow/Uncalled Function Checks.ts b/docs/playground/ko/3-7/Types and Code Flow/Uncalled Function Checks.ts new file mode 100644 index 00000000..2bdf76af --- /dev/null +++ b/docs/playground/ko/3-7/Types and Code Flow/Uncalled Function Checks.ts @@ -0,0 +1,41 @@ +//// { "compiler": {}, "order": 1} + +// 3.7에서는 if문 안에서 +// 함수의 반환 값 대신 함수를 잘못 사용하는 것을 +// 검사하는 기능이 추가되었습니다. + +// 이것은 함수가 존재하는 것을 알고 있으며 +// if문을 항상 참으로 할 때만 적용됩니다. + +// 선택적인 콜백과, 선택적이지 않은 콜백이 있는 +// 플러그인 인터페이스의 예시입니다. + +interface PluginSettings { + pluginShouldLoad?: () => void; + pluginIsActivated: () => void; +} + +declare const plugin: PluginSettings; + +// pluginShouldLoad가 존재하지 않을 수 있으므로, +// 다음 검사는 타당합니다. + +if (plugin.pluginShouldLoad) { + // pluginShouldLoad가 존재할 때의 처리. +} + +// 이는 3.6 이전에서 에러가 아니었습니다. + +if (plugin.pluginIsActivated) { + // 플러그인이 활성화되었을 때 무언가를 처리하려고 하는데, + // 메서드를 호출하는 대신 + // 프로퍼티로 사용했습니다. +} + +// pluginIsActivated는 언제나 존재하겠지만, +// if 블록 안에서 메서드가 호출되고 있으므로 +// TypeScript는 검사를 허용하고 있습니다. + +if (plugin.pluginIsActivated) { + plugin.pluginIsActivated(); +} diff --git a/docs/playground/ko/4-0/New TS Features/Unknown in Catch.ts b/docs/playground/ko/4-0/New TS Features/Unknown in Catch.ts new file mode 100644 index 00000000..75173dc7 --- /dev/null +++ b/docs/playground/ko/4-0/New TS Features/Unknown in Catch.ts @@ -0,0 +1,35 @@ +//// { "compiler": { "ts": "4.0.2" } } + +// JavaScript는 모든 값을 던질 수 있기 때문에 +// TypeScript는 오류 타입 선언을 지원하지 않습니다. + +try { + // .. +} catch (e) {} + +// 이것은 catch 절의 `e`가 기본적으로 any 타입인 것을 의미합니다. +// 이것은 임의의 속성에 접근할 수 있는 자유를 허용합니다. +// 4.0에서는 `any`와 `unknown`을 모두 허용하도록 catch절의 +// 타입 할당 제한을 완화했습니다. + +// any와 동일한 동작: +try { + // .. +} catch (e) { + e.stack +} + +// unknown을 사용한 명시적 동작: + +try { + // .. +} catch (e: unknown) { + // 타입 시스템이 `e`가 무엇인지 알기 전에 사용할 수 없습니다. + // 자세한 내용은 다음을 참조하세요: + // example:unknown-and-never + e.stack + + if (e instanceof SyntaxError) { + e.stack + } +} diff --git a/docs/playground/ko/TypeScript/Language/Structural Typing.ts b/docs/playground/ko/TypeScript/Language/Structural Typing.ts new file mode 100644 index 00000000..0a588d88 --- /dev/null +++ b/docs/playground/ko/TypeScript/Language/Structural Typing.ts @@ -0,0 +1,85 @@ +// TypeScript는 구조적 타입 시스템입니다. +// 구조적 타입 시스템은 타입을 비교할 때, +// TypeScript는 타입의 멤버만 고려한다는 것을 의미합니다. + +// 두 가지 타입을 만들 수 있지만, +// 서로 할당할 수 없는 명목적 타입 시스템과는 대조적입니다. +// example:nominal-typing 를 참고하세요. + +// 예를 들어, 구조적 타입 시스템에서 +// 이러한 두 가지 인터페이스는 서로 양도할 수 있습니다. + +interface Ball { + diameter: number; +} +interface Sphere { + diameter: number; +} + +let ball: Ball = { diameter: 10 }; +let sphere: Sphere = { diameter: 20 }; + +sphere = ball; +ball = sphere; + +// Ball과 Sphere의 모든 멤버를 +// 구조적으로 포함하는 타입을 추가하면, +// ball이나 sphere가 되도록 설정할 수도 있습니다. + +interface Tube { + diameter: number; + length: number; +} + +let tube: Tube = { diameter: 12, length: 3 }; + +tube = ball; +ball = tube; + +// ball은 length를 갖고 있지 않아서, tube 변수에 할당할 수 없습니다. +// 하지만, Ball의 모든 멤버는 +// tube 내부에 속하니 할당할 수 있습니다. + +// TypeScript는 타입의 각 멤버를 +// 서로 비교하여 동등한지 확인합니다. + +// 함수는 JavaScript에서 객체이며 +// 비슷한 방식으로 비교합니다. +// 매개변수에 유용한 추가 트릭이 하나 있습니다: + +let createBall = (diameter: number) => ({ diameter }); +let createSphere = (diameter: number, useInches: boolean) => { + return { diameter: useInches ? diameter * 0.39 : diameter }; +}; + +createSphere = createBall; +createBall = createSphere; + +// TypeScript는 매개변수의 (숫자)는 (숫자, 불린)과 같다고 하지만, +// (숫자, 불린)은 (숫자)와 같다고 하지 않습니다 + +// JavaScript 코드가 필요 없어 졌을 때 +// 매개변수 전달을 생략하는 게 아주 흔한 일이라서 +// TypeScript는 첫 번째 할당에 있는 불린을 버립니다. + +// 예를 들어 배열의 forEach의 콜백은 세 가지 매개변수를 갖고 있는데 +// 값, 인덱스, 전체 배열입니다. +// TypeScript가 매개변수 버리기를 제공하지 않았다면, +// 함수와 일치시키기 위해 모든 선택 사항을 포함했어야 합니다: + +[createBall(1), createBall(2)].forEach((ball, _index, _balls) => { + console.log(ball); +}); + +// 아무도 필요로 하지 않습니다. + +// 반환 타입은 객체처럼 간주하고, +// 일부 차이점은 위의 같은 객체 비교 규칙으로 비교합니다. + +let createRedBall = (diameter: number) => ({ diameter, color: "red" }); + +createBall = createRedBall; +createRedBall = createBall; + +// 첫 번째 할당은 동작하지만 (둘 다 diameter가 있음), +// 두 번째는 동작하지 않습니다. (ball은 color가 없음) diff --git a/docs/typescriptlang/fr/cheatsheets.ts b/docs/typescriptlang/fr/cheatsheets.ts new file mode 100644 index 00000000..4bed1dee --- /dev/null +++ b/docs/typescriptlang/fr/cheatsheets.ts @@ -0,0 +1,15 @@ +export const cheatCopy = { + cht_layout_title: "Cheat sheets", + cht_layout_description: + "Cheat sheets reprenant la syntaxe de TypeScript.", + cht_download: "Télécharger le zip", + cht_blurb_1: "Pages de documentation de la syntaxe téléchargeables pour les différentes parties du code TypeScript utilisé couramment.", + cht_blurb_2: "Apprenez-en plus sur les classes, les interfaces, les types et l'analyse du flux de contrôle.", + + cht_cfa: "Analyse du flux de contrôle", + cht_interfaces: "Interfaces", + cht_types: "Types", + cht_classes: "Classes", + cht_dl_title: "Télécharger les PDF et PNG", + cht_dl_subtitle: "A lire plus tard ou à imprimer", +} diff --git a/docs/typescriptlang/fr/community.ts b/docs/typescriptlang/fr/community.ts index f141403d..b33c9af6 100644 --- a/docs/typescriptlang/fr/community.ts +++ b/docs/typescriptlang/fr/community.ts @@ -1,19 +1,19 @@ export const comCopy = { - com_layout_title: 'Comment configurer TypeScript', // FIXME: Is this the right title for the community page? + com_layout_title: 'Ressources communautaires TypeScript', com_layout_description: "Échangez avec d'autres TypeScripters en ligne et hors ligne.", - com_headline: 'Échangez avec nous', // FIXME: I think this is not used anywhere + com_headline: 'Échangez avec nous', com_connect_online: 'En ligne', com_connect_online_description: - 'Dites nous ce qui marche, ce que vous souhaitez voir ajouté ou amélioré, et tenez vous au courant des nouvelles mises à jour.', + 'Dites nous ce qui marche, ce que vous souhaitez voir ajouté ou amélioré et restez au courant des nouvelles mises à jour.', com_online_stack_overflow_desc: - "Discutez avec vos proches et posez des questions sur TypeScript avec le tag 'typescript'", + "Discutez avec vos pairs et posez des questions sur TypeScript avec le tag 'typescript'", com_online_stack_overflow_tag: '', com_online_discord_header: 'Chat', com_online_discord_desc: "Discutez avec d'autres utilisateurs TypeScript dans le Chat communautaire TypeScript.", com_online_github_desc: - 'Vous avez trouvé un bug, ou souhaitez nous donner un feebdack constructif ?', + 'Vous avez trouvé un bug, ou souhaitez nous donner un commentaire constructif ?', com_online_github_href: 'Dites nous sur GitHub', com_online_twitter_desc: 'Restez à jour. Suivez-nous sur Twitter', com_online_blog_desc: diff --git a/docs/typescriptlang/fr/documentation.ts b/docs/typescriptlang/fr/documentation.ts new file mode 100644 index 00000000..f3d272d0 --- /dev/null +++ b/docs/typescriptlang/fr/documentation.ts @@ -0,0 +1,84 @@ +export const docCopy = { + doc_layout_title: "Le point de départ pour apprendre TypeScript", + doc_layout_description: + "Trouvez des projets de démarrage TypeScript : d'Angular à React ou Node.js et CLI.", + doc_bootstrap_title: "Outils de création pour les projets TypeScript", + doc_bootstrap_description: + "Toolchains pour la création de CLI, d'applications Web, d'API et d'applications.", + doc_headline: "Ressources d'apprentissage", + doc_headline_ts_for_js_title: "TS pour JS", // TODO: Remove, unused + doc_headline_ts_for_js_blurb: + "Vue d'ensemble de TypeScript pour les ingénieurs ayant des connaissances en JavaScript", // TODO: Remove, unused + doc_headline_ts_first_title: "Débuter avec TS", // TODO: Remove, unused + doc_headline_ts_first_blurb: + "Une introduction pour débutants à JavaScript et TypeScript", // TODO: Remove, unused + doc_headline_handbook_title: "Manuel", // TODO: This is not actually used on headline section, should be moved to the doc_learn section + doc_headline_handbook_blurb: "La documentation du langage TypeScript", + doc_headline_examples_title: "Exemples", // TODO: Remove, unused + doc_headline_examples_blurb: "Tutoriels concrets détaillés dans le playground", // TODO: Remove, unused + doc_start_a_project: "Commencer un nouveau projet", + doc_start_a_project_desc: + "Comme TypeScript est une extension de JavaScript, il n'a pas de modèle par défaut - il y en aurait trop. À la place, les projets ont leurs propres modèles de démarrage pour TypeScript avec leur propre contexte. Ces projets offrent des modèles qui prennent en charge TypeScript.", + doc_node_npm: "Node avec npm", + doc_node_npm_oclif_blurb: "Créez des outils en ligne de commande que vos utilisateurs adoreront", + doc_node_npm_gluegun_blurb: + "Une boîte à outils pratique pour créer des applications en ligne de commande utilisant TypeScript", + doc_node_npm_tsup_blurb: + "Empaquetez votre bibliothèque TypeScript sans aucune configuration, grâce à esbuild.", + doc_frameworks: "Frameworks web", + doc_frameworks_angular_blurb: "La plateforme du développeur web moderne", + doc_frameworks_ember_blurb: "Un framework pour les développeurs web ambitieux", + doc_frameworks_react_blurb: + "Une librairie JavaScript pour la création d'interfaces utilisateur", + doc_frameworks_vue_blurb: "Le framework JavaScript progressif", + doc_frameworks_ror_blurb: "Framework web avec des conventions plutôt que de la configuration", + doc_frameworks_asp_blurb: + "Un framework pour la création d'applications modernes, basées sur le cloud et connectées à l'Internet", + doc_apis: "API Node", + doc_apis_azure_blurb: "Construisez et déployez à partir de VS Code en quelques minutes", + doc_apis_feather_blurb: + "Un framework pour les applications en temps réel et les API REST", + doc_apis_graphql_blurb: "Créez votre serveur GraphQL en quelques secondes", + doc_apis_nest_blurb: + "Un framework Node.js progressif pour créer des applications efficaces et extensibles côté serveur", + doc_apis_node_blurb: "Un modèle de démarrage documenté par l'équipe TS", + doc_apis_wechat_blurb: "Utiliser le JSSDK WeChat avec TypeScript", + doc_apis_loopback_blurb: + "Un framework Node.js et TypeScript ultra-extensible pour la création d'API et de microservices", + doc_apis_fastify_blurb: "Un framework web rapide et léger pour Node.js", + doc_apis_foal_blurb: + "Un framework Node.js élégant et complet pour construire des applications web", + doc_react: "Projets React", + doc_react_create_blurb: "Configurez une application web moderne en exécutant une commande", + doc_react_gatsby_blurb: + "Aide les développeurs à créer des sites Web et des applications ultra-rapides", + doc_react_next_blurb: "Le framework React pour la mise en production", + doc_react_redwood_blurb: "Le framework JS pour les applications des startups", + doc_react_razzle_blurb: + "Applications JavaScript universelles à rendu serveur sans configuration", + doc_react_toolchains_title: "Toolchains recommandées", + doc_react_toolchains_blurb: "Recommendations de l'équipe React", + doc_apps: "Construire des applications", + doc_apps_electron_blurb: + "Créez des applications de bureau multiplateformes avec JavaScript, HTML et CSS", + doc_apps_expo_blurb: "Le moyen le plus rapide de créer une application", + doc_apps_react_native_blurb: "À apprendre une fois, pour écrire partout", + doc_apps_native_script_blurb: + "Framework open source pour la création d'applications mobiles véritablement natives", + doc_apps_make_code_blurb: + "Donne vie à l'informatique pour tous les étudiants grâce à des projets amusants", + doc_tooling: "Outils", + doc_tooling_babel_blurb: "Utilisez le JavaScript de nouvelle génération, dès aujourd'hui", + doc_tooling_parcel_blurb: + "Bundler d'applications web ultra-rapide et sans aucune configuration", + doc_tooling_vite_blurb: "Outils pour le frontend de dernière génération", + doc_tooling_webpack_blurb: "Regroupez vos ressources, scripts, images et styles", + doc_learn: "Déjà familier avec TypeScript ?", + doc_learn_3_5_release_notes_title: "Notes de mise à jour", + doc_learn_handbook_blurb: "Documentation du langage TypeScript", // TODO: Remove, unused + doc_learn_d_ts_title: "Guide d.ts", + doc_learn_d_ts_blurb: "Apprenez à déclarer la structure de votre JS", + doc_learn_playground_blurb: "Explorez et partagez du TypeScript en ligne", + doc_cheatsheets_subnav_title: "Cheat Sheets", + doc_learn_cheatsheets_blurb: "Syntaxe TypeScript en un clin d'œil", +} diff --git a/docs/typescriptlang/fr/dt.ts b/docs/typescriptlang/fr/dt.ts index e8ad4227..a884bf46 100644 --- a/docs/typescriptlang/fr/dt.ts +++ b/docs/typescriptlang/fr/dt.ts @@ -1,8 +1,8 @@ export const dtCopy = { dt_s_page_title: "Rechercher des paquets typés", - dt_s_title: "Rechercher un paquet", + dt_s_title: "Rechercher des types", dt_s_subtitle: - "Trouver des paquets npm qui ont des déclarations de types, soit intégrés ou sur Definitely Typed.", + "Trouvez des paquets npm qui ont des déclarations de types, soit intégrés ou sur Definitely Typed.", dt_s_match: "résultat", dt_s_matchs: "résultats", dt_s_match_exact: "Résultat exact", diff --git a/docs/typescriptlang/fr/footer.ts b/docs/typescriptlang/fr/footer.ts new file mode 100644 index 00000000..55311ab8 --- /dev/null +++ b/docs/typescriptlang/fr/footer.ts @@ -0,0 +1,8 @@ +export const footerCopy = { + footer_customize: "Personnaliser", + footer_site_colours: "Couleurs du site", + footer_code_font: "Police du code", + footer_site_colours_options_system: "Système", + footer_site_colours_options_always_light: "Toujours clair", + footer_site_colours_options_always_dark: "Toujours sombre", +} diff --git a/docs/typescriptlang/fr/fr.ts b/docs/typescriptlang/fr/fr.ts index 6ba8dca5..0155f4ed 100644 --- a/docs/typescriptlang/fr/fr.ts +++ b/docs/typescriptlang/fr/fr.ts @@ -1,16 +1,28 @@ import { defineMessages } from "react-intl"; import { Copy, messages as englishMessages } from "../en/en"; -import { comCopy } from "./community"; -import { dtCopy } from "./dt"; -import { handbookCopy } from "./handbook"; -import { headCopy } from "./head-seo"; -import { navCopy } from "./nav"; +import { cheatCopy } from "./cheatsheets" +import { comCopy } from "./community" +import { docCopy } from "./documentation" +import { dtCopy } from "./dt" +import { footerCopy } from "./footer" +import { handbookCopy } from "./handbook" +import { headCopy } from "./head-seo" +import { indexCopy } from "./index" +import { indexCopy as index2Copy } from "./index2" +import { navCopy } from "./nav" +import { playCopy } from "./playground" export const lang: Copy = defineMessages({ ...englishMessages, + ...navCopy, + ...docCopy, + ...headCopy, + ...indexCopy, + ...playCopy, ...comCopy, - ...dtCopy, ...handbookCopy, - ...headCopy, - ...navCopy, + ...dtCopy, + ...index2Copy, + ...footerCopy, + ...cheatCopy }); diff --git a/docs/typescriptlang/fr/handbook.ts b/docs/typescriptlang/fr/handbook.ts index 73fe9796..0674b46d 100644 --- a/docs/typescriptlang/fr/handbook.ts +++ b/docs/typescriptlang/fr/handbook.ts @@ -1,13 +1,16 @@ export const handbookCopy = { handb_prev: "Précédent", handb_next: "Suivant", - handb_on_this_page: "Dans cette page", + handb_on_this_page: "Sur cette page", handb_like_dislike_title: "Cette page est-elle utile ?", handb_like_desc: "Oui", handb_dislike_desc: "Non", handb_thanks: "Merci pour votre retour", handb_deprecated_title: "Cette page a été dépréciée", - handb_deprecated_subtitle: "Cette page du guide a été remplacé, ", + handb_deprecated_subtitle: "Cette page du guide a été remplacée, ", handb_deprecated_subtitle_link: "aller à la nouvelle page", handb_deprecated_subtitle_action: "Aller à la nouvelle page", + handb_experimental_title: "Cette page contient la documentation expérimentale", + handb_experimental_subtitle: "Le contenu concerne un sujet qui n'est pas encore définitif.", + }; diff --git a/docs/typescriptlang/fr/head-seo.ts b/docs/typescriptlang/fr/head-seo.ts index eae22e8a..a4bece4f 100644 --- a/docs/typescriptlang/fr/head-seo.ts +++ b/docs/typescriptlang/fr/head-seo.ts @@ -1,10 +1,9 @@ export const headCopy = { head_playground_title: - "TS Playground - Un éditeur en ligne pour explorer TypeScript et JavaScript", + "Playground TS - Un éditeur en ligne pour explorer TypeScript et JavaScript", head_playground_description: - "Playground vous permet d'écrire du TypeScript ou du JavaScript en ligne de manière sûre et partageable.", - tsconfig_title: - "Référence TSConfig - documentation sur toutes les options du fichier TSConfig", + "Le playground vous permet d'écrire du TypeScript ou du JavaScript en ligne de manière sûre et partageable.", + tsconfig_title: "Référence TSConfig - documentation sur toutes les options du fichier TSConfig", tsconfig_description: "De allowJs à useDefineForClassFields, la référence TSConfig documente les différents options du compilateur qui permettent de configurer un projet TypeScript.", playground_example_prefix: "Playground Exemple - ", diff --git a/docs/typescriptlang/fr/index.ts b/docs/typescriptlang/fr/index.ts new file mode 100644 index 00000000..12490a5e --- /dev/null +++ b/docs/typescriptlang/fr/index.ts @@ -0,0 +1,9 @@ +export const indexCopy = { + // The index page copy lives at index2.ts + index_releases: "Versions trimestrielles", + index_releases_pt1: "Notre prochaine version est ", + index_releases_pt2: ", qui est prévue pour ", + index_releases_released: "Publiée", + index_releases_beta: "Bêta", + index_releases_rc: "RC" +} diff --git a/docs/typescriptlang/fr/index2.ts b/docs/typescriptlang/fr/index2.ts new file mode 100644 index 00000000..bb85c290 --- /dev/null +++ b/docs/typescriptlang/fr/index2.ts @@ -0,0 +1,79 @@ +export const indexCopy = { + index_2_headline: + "TypeScript c'est JavaScript avec une syntaxe pour les types.", + index_2_byline: "TypeScript améliore JavaScript en ajoutant des types.", + index_2_summary: + "TypeScript est un langage de programmation fortement typé qui s'appuie sur JavaScript et offre de meilleurs outils à n'importe quelle échelle.", + + // Above the fold + index_2_cta_install: "Essayez TypeScript dès maintenant", + index_2_cta_install_subtitle: "En ligne ou via npm", + + index_2_cta_play: "Dans votre navigateur", + index_2_cta_play_subtitle: "via le playground", + + index_2_cta_download: "Sur votre ordinateur", + index_2_cta_download_subtitle: "via npm", + + // Editor titles + index_2_tab_1: "Vérifications de l'éditeur", + index_2_tab_2: "Autocomplétion", + index_2_tab_3: "Interfaces", + index_2_tab_4: "JSX", + index_2_tab_5: "ESNext", + + // Quick pitch + index_2_what_is: "Qu'est-ce que TypeScript ?", + index_2_what_is_js: "JavaScript et plus encore", + + index_2_what_is_js_copy: `TypeScript ajoute une syntaxe supplémentaire à JavaScript pour favoriser une intégration plus poussée avec votre éditeur. Détectez les erreurs au plus tôt dans votre éditeur.`, + index_2_trust: "Un résultat digne de confiance", + index_2_trust_copy: `Le code TypeScript peut être converti en JavaScript, qui peut être exécuté n'importe où où fonctionne JavaScript : dans un navigateur, sur Node.js ou Deno et dans vos applications.`, + index_2_scale: "La sécurité à l'échelle", + index_2_scale_copy: `TypeScript comprend le JavaScript et utilise l'inférence de type pour vous donner des outils de qualité sans code supplémentaire.`, + + // Links for getting started (this shows up twice) + index_2_started_title: "Commencer", + index_2_started_handbook: "Guide", + index_2_started_handbook_blurb: "Apprendre le langage", + index_2_install: "Installer TypeScript", + index_2_playground_blurb: "Essayer dans votre navigateur", + + index_2_migrate_1: "Fichier JavaScript", + index_2_migrate_2: "JavaScript avec vérification TS", + index_2_migrate_3: "JavaScript avec JSDoc", + index_2_migrate_4: "Fichier TypeScript", + + // Stories + OSS users` + index_2_migration_title: "Témoignages TypeScript", + index_2_migration_oss: "Open Source avec TypeScript", + + // Survey results + index_2_loved_by: "Apprécié par les développeurs", + index_2_loved_stack: `Élu 2e langage de programmation le plus apprécié dans l'enquête Stack Overflow 2020 Developer survey.`, + index_2_loved_state_js: `TypeScript a été utilisé par 78% des répondants à la State of JS 2020, avec 93% disant qu'ils l'utiliseraient à nouveau.`, + index_2_loved_state_js2: `TypeScript a reçu le prix de la "technologie la plus adoptée" sur la base de la croissance annuelle.`, + + // Show me some code + index_2_describe: "Décrivez vos données", + index_2_describe_blurb1: + "Décrivez la forme des objets et des fonctions dans votre code.", + index_2_describe_blurb2: + "Permettant de voir la documentation et les problèmes dans votre éditeur.", + + // Show how tsc 'works' + index_2_transform: "TypeScript devient JavaScript grâce à la touche de suppression.", + index_2_transform_1: "Fichier TypeScript.", + index_2_transform_2: "Les types sont retirés.", + index_2_transform_3: "Fichier JavaScript.", + + // Adopt TS gradually animations + index_2_adopt: "Adoptez TypeScript graduellement", + index_2_adopt_blurb_1: + "Appliquez des types à votre projet JavaScript progressivement, chaque étape améliore les capacités de votre éditeur et améliore votre codebase.", + index_2_adopt_blurb_2: + "Prenons ce code JavaScript incorrect, et voyons comment TypeScript peut détecter les erreurs dans votre éditeur.", + + index_2_adopt_info_1: + "Pas d'avertissements de l'éditeur dans les fichiers JavaScript.

Ce code plante au moment de l'exécution.", +} diff --git a/docs/typescriptlang/fr/nav.ts b/docs/typescriptlang/fr/nav.ts index af1b58c3..3b1dd160 100644 --- a/docs/typescriptlang/fr/nav.ts +++ b/docs/typescriptlang/fr/nav.ts @@ -9,13 +9,13 @@ export const navCopy = { nav_handbook: "Guide", nav_tools: "Outils", nav_search_placeholder: "Rechercher", - nav_search_aria: "Recherche sur le site TypeScript", + nav_search_aria: "Rechercher sur le site TypeScript", // let me know if you can't make this work in your lang: // TypeScript X.Y [stable][between?]Z.Y[beta/rc] nav_version_stable_prefix: "est maintenant disponible", nav_version_between: ", ", nav_version_beta_prefix: "est actuellement en bêta.", - nav_version_rc_prefix: "est une version candidate, essayer la.", + nav_version_rc_prefix: "est une version candidate, essayez-la.", nav_this_page_in_your_lang: "Cette page est disponible dans votre langue", nav_this_page_in_your_lang_open: "Ouvrir", nav_this_page_in_your_lang_no_more: "Ne plus montrer", diff --git a/docs/typescriptlang/fr/playground.ts b/docs/typescriptlang/fr/playground.ts new file mode 100644 index 00000000..e9ad10be --- /dev/null +++ b/docs/typescriptlang/fr/playground.ts @@ -0,0 +1,98 @@ +export const playCopy = { + play_subnav_title: "Playground", + play_subnav_config: "TS Config", + play_config_language_blurb: "Quel langage doit être utilisé dans l'éditeur", + play_subnav_handbook: "Aide", + play_subnav_examples: "Exemples", + play_subnav_examples_close: "Fermer", + play_subnav_whatsnew: "Nouveautés", + play_subnav_settings: "Paramètres", + play_settings_tabs_settings: "Onglets de la barre latérale", + play_downloading_typescript: "Téléchargement de TypeScript...", // when loading + play_downloading_version: "Version...", // when loading + play_toolbar_run: "Exécuter", + play_toolbar_export: "Exporter", + play_toolbar_share: "Partager", + play_sidebar_js: ".JS", + play_sidebar_dts: ".D.TS", + play_sidebar_errors: "Erreurs", + play_sidebar_errors_no_errors: "Pas d'erreurs", + play_sidebar_logs: "Logs", + play_sidebar_logs_no_logs: "Pas de logs", + play_sidebar_options: "Options", + play_sidebar_options_restart_required: "Besoin de recharger la page", + play_sidebar_options_disable_ata: "Désactiver l'AAT", + play_sidebar_options_disable_ata_copy: + "Désactive l'acquisition automatique des types pour les imports et les requires.", + play_sidebar_options_disable_save: "Désactiver la sauvegarde automatique", + play_sidebar_options_disable_save_copy: + "Désactive le changement de l'URL lorsque vous êtes en train de taper.", + play_sidebar_plugins: "Plugins", + play_sidebar_featured_plugins: "Plugins mis en avant", + play_sidebar_plugins_options_external: + "Plugins tiers venant de npm", + play_sidebar_plugins_options_external_warning: + "Attention : Le code des plugins provient de tiers.", + play_sidebar_plugins_options_modules: "Modules npm personnalisés", + play_sidebar_plugins_options_modules_placeholder: "Nom du module venant d'npm.", + play_sidebar_plugins_plugin_dev: "Développement de plugins", + play_sidebar_plugins_plugin_dev_option: + "Connectez-vous sur localhost:5000", + play_sidebar_plugins_plugin_dev_copy: + "Essayer de se connecter automatiquement à un plugin du playground en mode de développement. Vous pouvez commencer à créer un plugin ici.", + play_export_report_issue: "Signaler un problème sur GitHub concernant TypeScript", + play_export_tweet_md: "Tweeter un lien vers ce Playground", + play_export_copy_md: "Copier sous forme de problème Markdown", + play_export_copy_link: "Copier sous forme de lien Markdown", + play_export_copy_link_preview: "Copier sous forme de lien Markdown avec aperçu", + play_export_tsast: "Ouvrir dans le lecteur d'AST TypeScript", + play_export_bugworkbench: "Ouvrir dans Bug Workbench", + play_export_vscode_dev_play: "Ouvrir dans le Playground TS de VSCode (alpha)", + play_export_sandbox: "Ouvrir dans CodeSandbox", + play_export_stackblitz: "Ouvrir dans StackBlitz", + play_export_clipboard: "URL copiée dans le presse-papiers", + play_esm_mode: "Passage en mode ESM", + play_clear_logs: "Logs effacés", + play_run_js: "JavaScript exécuté", + play_run_ts: "TypeScript transpilé exécuté", + play_run_js_fail: "Erreur lors de l'exécution du JavaScript :", + play_default_code_sample: `// Bienvenue dans le Playground TypeScript, c'est un site web +// qui vous permet d'écrire, de partager et d'apprendre TypeScript. + +// Vous pouvez voir cela de trois façons différentes : +// +// - Un endroit pour apprendre TypeScript où il n'y a rien à craindre +// - Un endroit pour explorer la syntaxe TypeScript et partager des URL avec les autres +// - Un bac à sable pour expérimenter les différentes fonctionnalités du compilateur TypeScript + +const anExampleVariable = "Hello World" +console.log(anExampleVariable) + +// Pour en savoir plus sur le langage, cliquez ci-dessus dans "Exemples" ou "Nouveautés". +// Sinon, commencez par supprimer ces commentaires et le monde sera votre terrain de jeu. + `, + + play_sidebar_js_title: "JavaScript", + play_sidebar_js_blurb: "Affiche le JS transpilé", + + play_sidebar_dts_title: "Fichiers de définition", + play_sidebar_dts_blurb: "Montre le fichier .d.ts produit par votre code", + + play_sidebar_err_title: "Erreurs de compilation", + play_sidebar_err_blurb: "Affiche les erreurs de compilation dans leur intégralité", + + play_sidebar_run_title: "Exécute le JavaScript dans le navigateur", + play_sidebar_run_blurb: + "Affiche le résultat de l'exécution du JavaScript dans l'éditeur", + + play_sidebar_plugins_title: "Gérer les plugins du Playground", + play_sidebar_plugins_blurb: + "Gère l'ajout/la suppression de plugins tiers dans le playground", + + play_sidebar_ast_title: "[WIP] Lecteur d'AST", + play_sidebar_ast_blurb: "Inspecte l'AST TypeScript", + + play_sidebar_tools_filter_placeholder: "Filtre", + // Notes: + // Compiler flag information is all from the tsconfig reference info +} diff --git a/docs/typescriptlang/pt/community.ts b/docs/typescriptlang/pt/community.ts index e3932a9c..429b2141 100644 --- a/docs/typescriptlang/pt/community.ts +++ b/docs/typescriptlang/pt/community.ts @@ -7,7 +7,7 @@ export const comCopy = { com_connect_online_description: "Conte-nos o que está funcionando bem, o que quer ver adicionado ou aprimorado e descubra novas atualizações.", com_online_stack_overflow_desc: - "Conecte-se com colegas e faça perguntas sobre Typescript usando a tag 'typescript'", + "Conecte-se com colegas e faça perguntas sobre TypeScript usando a tag 'typescript'", com_online_stack_overflow_tag: "", com_online_discord_header: "Chat", com_online_discord_desc: @@ -17,8 +17,8 @@ export const comCopy = { com_online_github_href: "Conte-nos no Github", com_online_twitter_desc: "Mantenha-se atualizado. Nos siga no Twitter", com_online_blog_desc: - "Aprenda sobre os desenvolvimentos mais recentes do Typescript no nosso", //... blog - com_online_typed_desc: "Definições de tipos de Typescript.", + "Aprenda sobre os desenvolvimentos mais recentes do TypeScript no nosso", //... blog + com_online_typed_desc: "Definições de tipos de TypeScript.", com_online_typed_href: "Navegue pelas milhares de", com_online_typed_available_for: "bibliotecas e frameworks disponíveis.", com_person: "Conecte-se pessoalmente", diff --git a/docs/typescriptlang/pt/documentation.ts b/docs/typescriptlang/pt/documentation.ts index e22fecb7..9cef257a 100644 --- a/docs/typescriptlang/pt/documentation.ts +++ b/docs/typescriptlang/pt/documentation.ts @@ -22,7 +22,7 @@ export const docCopy = { doc_node_npm_oclif_blurb: "Crie ferramentas de linha de comando que seus usuários amam", doc_node_npm_gluegun_blurb: - "Uma maravilhosa coleção de ferramentas para construir aplicativos de linha de comando em Typescript", + "Uma maravilhosa coleção de ferramentas para construir aplicativos de linha de comando em TypeScript", doc_frameworks: "Frameworks Web", doc_frameworks_angular_blurb: "Transforme o trabalho de escrever apps lindos em algo alegre e divertido", @@ -45,7 +45,7 @@ export const docCopy = { "Um modelo bem documentado, cortesia do time do TypeScript", doc_apis_wechat_blurb: "Use o JSSDK do WeChat com TypeScript", doc_apis_loopback_blurb: - "Um framework Node.js e Typescript altamente expansível para construir APIs e microsserviços", + "Um framework Node.js e TypeScript altamente expansível para construir APIs e microsserviços", doc_apis_fastify_blurb: "Um framework web rápido e de baixo custo computacional para Node.js", doc_react: "Projetos em React", @@ -67,15 +67,15 @@ export const docCopy = { doc_apps_make_code_blurb: "Traga à vida ciência da computação para qualquer estudante com projetos divertidos", doc_tooling: "Ferramentas", - doc_tooling_babel_blurb: "Use Javascript da próxima geração, hoje", + doc_tooling_babel_blurb: "Use JavaScript da próxima geração, hoje", doc_tooling_parcel_blurb: "Bundler de aplicações web incrivelmente rápido, sem configuração necessária", - doc_tooling_webpack_blurb: "Agrupe seus recursos, scripts, images e estilos", - doc_learn: "Já conhece Typescript?", + doc_tooling_webpack_blurb: "Agrupe seus recursos, scripts, imagens e estilos", + doc_learn: "Já conhece TypeScript?", doc_learn_3_5_release_notes_title: "Notas de versão", doc_learn_3_5_release_notes_blurb: "Notas da versão 3.5", doc_learn_handbook_blurb: "Referência da linguagem TypeScript", doc_learn_d_ts_title: "Guia d.ts", doc_learn_d_ts_blurb: "Aprenda como declarar a forma de JS", - doc_learn_playground_blurb: "Explore and compartilhe TypeScript online", + doc_learn_playground_blurb: "Explore e compartilhe TypeScript online", } diff --git a/docs/typescriptlang/pt/index.ts b/docs/typescriptlang/pt/index.ts index 88a53e72..f80d92d9 100644 --- a/docs/typescriptlang/pt/index.ts +++ b/docs/typescriptlang/pt/index.ts @@ -1,49 +1,52 @@ export const indexCopy = { - index_headline: "Javascript Tipado em Qualquer Escala.", - index_byline: "O TypeScript estende o JavaScript adicionando tipos.", - index_summary: - "Ao compreender JavaScript, TypeScript economiza seu tempo em detectar erros e fornecer correções antes de executar o código.", - index_locations: - "Qualquer navegador, Qualquer SO, em qualquer lugar onde Javascript rodar. Completamente código aberto.", + index_2_headline: + "TypeScript é JavaScript com sintaxe para tipos.", + index_2_byline: "O TypeScript estende o JavaScript adicionando tipos.", + index_2_summary: + "TypeScript é uma linguagem de programação fortemente tipada que se baseia em JavaScript, oferecendo melhores ferramentas em qualquer escala.", + index_2_locations: + "Qualquer navegador, Qualquer SO, em qualquer lugar onde JavaScript rodar. Completamente código aberto.", - index_cta_play: "Tente no seu navegador", - index_cta_install: "Instale localmente", + index_2_cta_play: "Tente no seu navegador", + index_2_cta_install: "Instale localmente", - index_what_is: "O que é TypeScript?", + index_2_what_is: "O que é TypeScript?", - index_what_is_js: "JavaScript e Mais", - index_what_is_js_copy: ` -

TypeScript é uma linguagem código aberto construida em cima do Javascript, uma das ferramentas mais usadas do mundo, adicionando definições de tipagem estáticas

+ index_2_what_is_js: "JavaScript e Mais", + index_2_what_is_js_copy: `O TypeScript adiciona sintaxe adicional ao JavaScript para oferecer suporte a uma integração mais estreita com seu editor. Detecte erros mais cedo em seu editor.`, -

Tipos fornecem um jeito de descrever a forma de um objeto, fornecendo melhor documentação, e permitindo que o TypeScript valide se seu código está funcionando corretamente.

+ index_2_trust: "Um Resultado Que Você Pode Confiar", + index_2_trust_copy: + "O código TypeScript é convertido em JavaScript, que funciona em qualquer lugar em que o JavaScript é executado: em um navegador, em Node.js ou Deno e em seus aplicativos.", + index_2_trust_copy_a: `Todo código JavaScript válido é também um código TypeScript. Você pode obter erros de verificação de tipagem, mas isso não vai impedi-lo de executar o JavaScript resultante. Embora você possa optar por ser mais rígido, isso significa que você ainda está no controle.`, + index_2_trust_copy_b: `Código TypeScript é transformado em código JavaScript através do compilador do TypeScript ou Babel. Esse JavaScript é um código limpo e simples que roda em qualquer lugar que o JavaScript possa ser executado: em um navegador, no Node.JS ou em seus aplicativos.`, -

Tipar o seu código pode ser opcional no Typescript, pois a inferência de tipo permite que você obtenha muito poder sem escrever código adicional.

`, + index_2_scale: "Segurança em Escala", + index_2_scale_copy: + "O TypeScript entende JavaScript e usa inferência de tipos para fornecer ótimas ferramentas sem código adicional.", - index_trust: "Um Resultado Que Você Pode Confiar", - index_trust_copy_a: `Todo código JavaScript válido é também um código Typescript. Você pode obter erros de verificação de tipagem, mas isso não vai impedi-lo de executar o JavaScript resultante. Embora você possa optar por ser mais rígido, isso significa que você ainda está no controle.`, - index_trust_copy_b: `Código TypeScript é transformado em código JavaScript através do compilador do TypeScript ou Babel. Esse JavaScript é um código limpo e simples que roda em qualquer lugar que o JavaScript possa ser executado: em um navegador, no Node.JS ou em seus aplicativos.`, - index_standards: "Evoluindo com Padrões", - index_standards_copy: ` -

O time do TypeScript contribui para o comitê TC39 que ajudam a guiar a evolução do Javascript.

+ index_2_standards: "Evoluindo com Padrões", + index_2_standards_copy: ` +

O time do TypeScript contribui para o comitê TC39 que ajudam a guiar a evolução do JavaScript.

Quando as novas propostas atingem o estágio 3, eles estão prontos para inclusão no TypeScript.

Por exemplo, a equipe do TypeScript defendeu propostas como Encadeamento opcional, Operador de coalescência nula, Throw Expressions e RegExp Match Indices.

`, - index_gradual: "Adoção Gradual", - index_gradual_copy: ` + index_2_gradual: "Adoção Gradual", + index_2_gradual_copy: `

Adotar TypeScript não é uma escolha binária, você pode começar anotando o JavaScript existente com JSDoc, e então trocar alguns arquivos para serem checados através do TypeScript e com o tempo preparar todo seu código para ser convertido completamente

A inferência de tipo do TypeScript significa que você não precisa fazer anotações em seu código até que queira mais segurança.

`, - index_dts: "Tipagem Em Todos Os Lugares", - index_dts_copy: ` + index_2_dts: "Tipagem Em Todos Os Lugares", + index_2_dts_copy: `

A maior parte do mundo do JavaScript não é tipada e a inferência só pode ir até certo ponto. Para resolver isso, a equipe do TypeScript ajuda a manter

Definitely Typed
- um projeto da comunidade para fornecer tipos e documentação para bibliotecas JavaScript existente.

Este projeto permite que a comunidade mantenha definições de tipo para bibliotecas JavaScript sem colocar pressão extra sobre seus mantenedores.

`, - index_tools: "Ferramentas Consistentemente Boas", - index_tools_copy: ` + index_2_tools: "Ferramentas Consistentemente Boas", + index_2_tools_copy: `

Ao lidar com grande parte da integração do editor dentro do TypeScript, você pode obter uma experiência consistente de trabalho em muitos editores.

Isso permite que você alterne facilmente entre editores como Visual Studio , Visual Studio Code , Nova , Atom , Texto sublime , Emacs , Vim , WebStorm e Eclipse .

@@ -51,29 +54,43 @@ export const indexCopy = {

A integração do editor do TypeScript suporta JavaScript, então é bem provável que você já esteja usando o TypeScript nos bastidores. `, - index_started_title: "Iniciando", - index_started_handbook: "Manual", - index_started_handbook_blurb: "Aprenda a linguagem", - index_started_docs: "Comece um Projeto", - index_started_docs_blurb: "Encontre uma ferramenta de bootstrapping", - index_started_tooling: "Ferramentas", - index_started_tooling_blurb: "Aprofunde-se no TypeScript", - index_started_community: "Comunidade", - index_started_community_blurb: "Matenha-se atualizado", - index_install: "Instale TypeScript", - index_install_ref: ` + index_2_started_title: "Iniciando", + index_2_started_handbook: "Manual", + index_2_started_handbook_blurb: "Aprenda a linguagem", + index_2_playground_blurb: "Tente em seu navegador", + index_2_started_docs: "Comece um Projeto", + index_2_started_docs_blurb: "Encontre uma ferramenta de bootstrapping", + index_2_started_tooling: "Ferramentas", + index_2_started_tooling_blurb: "Aprofunde-se no TypeScript", + index_2_started_community: "Comunidade", + index_2_started_community_blurb: "Matenha-se atualizado", + index_2_install: "Instale TypeScript", + index_2_install_ref: `

Você pode instalar TypeScript através do npm

E então rodar o compilador através do tsc

npx tsc

Aprenda mais como sobre adicionar TypeScript na suas aplicações na página de instalação `, - index_releases: "Lançamentos Trimestrais", - index_releases_pt1: "Nosso próximo lançamento é ", - index_releases_pt2: ", que está planejado para ", - index_releases_released: "Lançados", - index_releases_beta: "Beta", - index_releases_rc: "RC", - - index_migration_title: "Historias de Migrações", - index_migration_oss: "Código aberto com TypeScript", - index_videos_title: "Veja o TypeScript em Ação", -} + index_2_adopt: "Adote o TypeScript Gradualmente", + index_2_adopt_blurb_1: + "Aplique tipos ao seu projeto JavaScript de forma incremental, cada etapa melhora o suporte ao editor e melhora sua base de código", + index_2_adopt_blurb_2: + "Vamos pegar esse código JavaScript incorreto e ver como o TypeScript pode detectar erros em seu editor.", + + index_2_migrate_1: "Arquivo JavaScript", + index_2_migrate_2: "JavaScript com TS Check", + index_2_migrate_3: "JavaScript com JSDoc", + index_2_migrate_4: "Arquivo TypeScript", + + index_2_loved_by: "Amado por desenvolvedores", + + index_2_releases: "Lançamentos Trimestrais", + index_2_releases_pt1: "Nosso próximo lançamento é ", + index_2_releases_pt2: ", que está planejado para ", + index_2_releases_released: "Lançados", + index_2_releases_beta: "Beta", + index_2_releases_rc: "RC", + + index_2_migration_title: "Historias de Migrações", + index_2_migration_oss: "Código aberto com TypeScript", + index_2_videos_title: "Veja o TypeScript em Ação", +} \ No newline at end of file