microsoft / TypeScript-Website-Localizations

A repo for the TypeScript Website localizations
Creative Commons Attribution 4.0 International
116 stars 129 forks source link

Fix minor typo in ko/ #217

Closed yusunghyun closed 1 year ago

yusunghyun commented 1 year ago

Fix Typo

github-actions[bot] commented 1 year ago

Thanks for the PR!

This section of the codebase is owned by @bumkeyy, @yeonjuan, @guyeol, and @dvlprsh - if they write a comment saying "LGTM" then it will be merged.

github-actions[bot] commented 1 year ago
Translation of Modules.md * * * title: Modules layout: docs permalink: /ko/docs/handbook/modules.html oneline: How modules work in TypeScript ## translatable: true Starting with ECMAScript 2015, JavaScript has a module concept. TypeScript shares this concept. The module runs within its own scope, not in a global scope; In other words, variables, functions, classes, etc. declared within the module are [`export` form](#export) It is not visible outside the module unless explicitly exported using one of them. Conversely, in order to use the exported variables, functions, classes, interfaces, etc. from other modules, [`import` form](#import) You must import using one of them. The module is declarative; The relationships between modules are specified from the file-level imports and exports perspectives. The module uses the module loader to import other modules. At runtime, the module loader must find and execute all dependencies of the module before running the module. Famous module loaders used in JavaScript include: [CommonJS](https://en.wikipedia.org/wiki/CommonJS) Node.js loader for modules and web applications [AMD](https://github.com/amdjs/amdjs-api/blob/master/AMD.md) For modules [RequireJS](https://requirejs.org/) There is a loader. Like ECMAScript 2015, TypeScript uses top-level `import` or `export`is considered a module. Conversely, the top-level `import` or `export` Files that do not have a declaration are treated as scripts that can be used in the global scope (as well as in modules). # Export ## Exporting a declaration `export` You can export all declarations (variables, functions, classes, type aliases, interfaces) by adding keywords. ##### StringValidator.ts ```ts export interface StringValidator { isAcceptable(s: string): boolean; } ``` ##### ZipCodeValidator.ts ```ts import { StringValidator } from "./StringValidator"; export const numberRegexp = /^[0-9]+$/; export class ZipCodeValidator implements StringValidator { isAcceptable(s: string) { return s.length === 5 && numberRegexp.test(s); } } ``` ## Export statements The Export statement comes in handy when you need to rename something to export for the user. The above example could be written as follows: ```ts class ZipCodeValidator implements StringValidator { isAcceptable(s: string) { return s.length === 5 && numberRegexp.test(s); } } export { ZipCodeValidator }; export { ZipCodeValidator as mainValidator }; ``` ## Re-export (Re-exports) Often, a module extends other modules and partially exposes some of its functionality. Re-export does not import regionally, nor does it introduce local variables. ##### ParseIntBasedZipCodeValidator.ts ```ts export class ParseIntBasedZipCodeValidator { isAcceptable(s: string) { return s.length === 5 && parseInt(s).toString() === s; } } // 기존 validator의 이름을 변경 후 export export {ZipCodeValidator as RegExpBasedZipCodeValidator} from "./ZipCodeValidator"; ``` Optionally, one module can wrap one or multiple modules, `export * from "module"` You can combine everything you do using the export syntax. ##### AllValidators.ts ```ts export * from "./StringValidator"; // 'StringValidator' 인터페이스를 내보냄 export * from "./ZipCodeValidator"; // 'ZipCodeValidator' 와 const 'numberRegexp' 클래스를 내보냄 export * from "./ParseIntBasedZipCodeValidator"; // 'ParseIntBasedZipCodeValidator' 클래스를 내보냄 // 'ZipCodeValidator.ts' 모듈 에 있는 // 'ZipCodeValidator' 클래스를 // 'RegExpBasedZipCodeValidator' 라는 별칭으로 다시 내보냄 ``` # Import Import is as easy as exporting from a module. The export declaration is below `import` Use one of the forms to import: ## Import a single export from a module ```ts import { ZipCodeValidator } from "./ZipCodeValidator"; let myValidator = new ZipCodeValidator(); ``` You can import it by modifying the name. ```ts import { ZipCodeValidator as ZCV } from "./ZipCodeValidator"; let myValidator = new ZCV(); ``` ## Import the entire module into a single variable, and use it to access the module exports ```ts import * as validator from "./ZipCodeValidator"; let myValidator = new validator.ZipCodeValidator(); ``` ## Import a module for side-effects only Although not recommended, some modules are set to some global state so that they can be used by others. These modules either don't have any exports, or the user is not interested in them. To import these modules, use the following: ```ts import "./my-module.js" ``` ## Importing Types Prior to TypeScript 3.8, `import`I was able to import the type using . In TypeScript 3.8, `import` Door, or `import type`You can import types using the ```ts // 동일한 import를 재사용하기 import {APIResponseType} from "./api"; // 명시적으로 import type을 사용하기 import type {APIResponseType} from "./api"; ``` `import type`is always removed from JavaScript, and tools like Babel `isolatedModules` Compiler flags allow you to make better assumptions about your code. [3.8 Release Notes](https://devblogs.microsoft.com/typescript/announcing-typescript-3-8-beta/#type-only-imports-exports)You can read more information at # Default exports Each module is optionally `default` You can export export. The default export is `default` It is represented by keywords; One per module `default` Export only. `default` export uses a different import form to import. `default` Exports are really convenient. For example, a library like jQuery would use `jQuery` or `$`You can have a default export such as, `$`I `jQuery`You can import it with a name such as ##### [JQuery.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/jquery/JQuery.d.ts) ```ts declare let $: JQuery; export default $; ``` ##### App.ts ```ts import $ from "jquery"; $("button.continue").html( "Next Step..." ); ``` Class and function declarations can be written directly with default exports. The default export class and function declaration names are optional. ##### ZipCodeValidator.ts ```ts export default class ZipCodeValidator { static numberRegexp = /^[0-9]+$/; isAcceptable(s: string) { return s.length === 5 && ZipCodeValidator.numberRegexp.test(s); } } ``` ##### Test.ts ```ts import validator from "./ZipCodeValidator"; let myValidator = new validator(); ``` or ##### StaticZipCodeValidator.ts ```ts const numberRegexp = /^[0-9]+$/; export default function (s: string) { return s.length === 5 && numberRegexp.test(s); } ``` ##### Test.ts ```ts import validate from "./StaticZipCodeValidator"; let strings = ["Hello", "98052", "101"]; // validate 함수 사용하기 strings.forEach(s => { console.log(`"${s}" ${validate(s) ? "matches" : "does not match"}`); }); ``` `default` Exports can also be valued: ##### OneTwoThree.ts ```ts export default "123"; ``` ##### Log.ts ```ts import num from "./OneTwoThree"; console.log(num); // "123" ``` ## Export all as x In TypeScript 3.8, when the following name is re-exported to another module, it is like a shortcut: `export * as ns`You can use: ```ts export * as utilities from "./utilities"; ``` If you take all the dependencies from the module and make them into exported fields, you can import them as follows: ```ts import { utilities } from "./index"; ``` # `export =`and `import = require()` (`export =` and `import = require()`) Both CommonJS and AMD typically include all exports of the module. `exports` It has the concept of an object. In addition `exports` It also supports replacing objects with single, user-defined objects. Default exports act as a fallback to this behavior; However, the two are not compatible. TypeScript is used to model existing CommonJS and AMD workflows. `export =`Support. `export =` The syntax specifies a single object that is exported from the module. It can be a class, interface, namespace, function, or enumeration. `export = `When exporting a module using TypeScript-specific `import module = require("module")`to import the module. ##### ZipCodeValidator.ts ```ts let numberRegexp = /^[0-9]+$/; class ZipCodeValidator { isAcceptable(s: string) { return s.length === 5 && numberRegexp.test(s); } } export = ZipCodeValidator; ``` ##### Test.ts ```ts import zip = require("./ZipCodeValidator"); // 시험용 샘플 let strings = ["Hello", "98052", "101"]; // 사용할 Validators let validator = new zip(); // 각 문자열이 각 validator를 통과했는지 보여줍니다 strings.forEach(s => { console.log(`"${ s }" - ${ validator.isAcceptable(s) ? "matches" : "does not match" }`); }); ``` # Code Generation for Modules During compilation, depending on the specified module target, the compiler sends Node.js ([CommonJS](http://wiki.commonjs.org/wiki/CommonJS)), require.js ([AMD](https://github.com/amdjs/amdjs-api/wiki/AMD)), [UMD](https://github.com/umdjs/umd), [SystemJS](https://github.com/systemjs/systemjs)or [ECMAScript 2015 native modules](http://www.ecma-international.org/ecma-262/6.0/#sec-modules) (ES6) Module-Generate code suitable for loading systems. In the generated code, `define`, `require` and `register` For more information about the calling function, check the documentation for each module loader. This simple example shows how the names used during import and export are converted to module loading code. ##### SimpleModule.ts ```ts import m = require("mod"); export let t = m.something + 1; ``` ##### AMD / RequireJS SimpleModule.js ```js define(["require", "exports", "./mod"], function (require, exports, mod_1) { exports.t = mod_1.something + 1; }); ``` ##### CommonJS / Node SimpleModule.js ```js var mod_1 = require("./mod"); exports.t = mod_1.something + 1; ``` ##### UMD SimpleModule.js ```js (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "./mod"], factory); } })(function (require, exports) { var mod_1 = require("./mod"); exports.t = mod_1.something + 1; }); ``` ##### System SimpleModule.js ```js System.register(["./mod"], function(exports_1) { var mod_1; var t; return { setters:[ function (mod_1_1) { mod_1 = mod_1_1; }], execute: function() { exports_1("t", t = mod_1.something + 1); } } }); ``` ##### Native ECMAScript 2015 modules SimpleModule.js ```js import { something } from "./mod"; export var t = something + 1; ``` # Simple Example Below, we incorporate the Validator implementation used in the previous example to export with a single name in each module. To compile, you must specify the module target on the command line. For Node.js: `--module commonjs`use; For require.js `--module amd`Use . Like what: ```Shell tsc --module commonjs Test.ts ``` Once compiled, each module has a separate `.js`file. As with reference tags, the compiler uses the `import`Follow the statement to compile the dependent files. ##### Validation.ts ```ts export interface StringValidator { isAcceptable(s: string): boolean; } ``` ##### LettersOnlyValidator.ts ```ts import { StringValidator } from "./Validation"; const lettersRegexp = /^[A-Za-z]+$/; export class LettersOnlyValidator implements StringValidator { isAcceptable(s: string) { return lettersRegexp.test(s); } } ``` ##### ZipCodeValidator.ts ```ts import { StringValidator } from "./Validation"; const numberRegexp = /^[0-9]+$/; export class ZipCodeValidator implements StringValidator { isAcceptable(s: string) { return s.length === 5 && numberRegexp.test(s); } } ``` ##### Test.ts ```ts import { StringValidator } from "./Validation"; import { ZipCodeValidator } from "./ZipCodeValidator"; import { LettersOnlyValidator } from "./LettersOnlyValidator"; // 시험용 샘플 let strings = ["Hello", "98052", "101"]; // 사용할 validator let validators: { [s: string]: StringValidator; } = {}; validators["ZIP code"] = new ZipCodeValidator(); validators["Letters only"] = new LettersOnlyValidator(); // 각 문자열이 validator를 통과하는지 보여줌 strings.forEach(s => { for (let name in validators) { console.log(`"${ s }" - ${ validators[name].isAcceptable(s) ? "matches" : "does not match" } ${ name }`); } }); ``` # Optional Module Loading and Other Advanced Loading Scenarios Depending on the situation, you can make the module load only under certain conditions. In TypeScript, you can use the patterns below to implement this and other advanced loading scenarios to invoke the module loader directly without losing the stability of the type. The compiler detects the use of each module within the exposed JavaScript. If a module identifier is used only as a type indication and not as an expression, the `require` The call does not occur. Removing unused references can optimize performance, and you can selectively load those modules. The core idea of this pattern is `import id = require("...")` It means that it is possible to access the type exposed as a module through the door. below `if` As you can see in the block, the module loader is (`require`via) is called dynamically. This feature leverages reference-remove optimization, so modules can be loaded only when needed. For that pattern to work, `import`It is important to note that symbols defined by are used only in type positions (i.e. not in JavaScript emit positions). In order to maintain type safety, `typeof` You can use keywords. `typeof` When a keyword is used in the type position, it creates the type of the value, in this case the type of the module. ##### Dynamic Module Loading in Node.js .js ```ts declare function require(moduleName: string): any; import { ZipCodeValidator as Zip } from "./ZipCodeValidator"; if (needZipValidation) { let ZipCodeValidator: typeof Zip = require("./ZipCodeValidator"); let validator = new ZipCodeValidator(); if (validator.isAcceptable("...")) { /* ... */ } } ``` ##### Sample: Dynamic Module Loading in require.js .js ```ts declare function require(moduleNames: string[], onLoad: (...args: any[]) => void): void; import * as Zip from "./ZipCodeValidator"; if (needZipValidation) { require(["./ZipCodeValidator"], (ZipCodeValidator: typeof Zip) => { let validator = new ZipCodeValidator.ZipCodeValidator(); if (validator.isAcceptable("...")) { /* ... */ } }); } ``` ##### Sample.js: Dynamic Module Loading in System.js ```ts declare const System: any; import { ZipCodeValidator as Zip } from "./ZipCodeValidator"; if (needZipValidation) { System.import("./ZipCodeValidator").then((ZipCodeValidator: typeof Zip) => { var x = new ZipCodeValidator(); if (x.isAcceptable("...")) { /* ... */ } }); } ``` # Working with Other JavaScript Libraries To describe what a library looks like that isn't written in TypeScript, you need to declare the API that exposes the library. We call declarations that do not define an implementation "ambient". These declarations are generally `.d.ts` It is defined in the file. If you are familiar with C/C++, `.h` You can think of it as a file. Let's look at some examples. ## Ambient Modules In Node.js most tasks are performed by loading one or more modules. As a top-level export declaration, each module is declared `.d.ts` file, but one larger `.d.ts` It is more convenient to create modules from files. To do this, we use a structure similar to the ambient namespace, but with the quoted module name and the `module` Use keywords. Like what: ##### node.d.ts (brief excerpt) ```ts declare module "url" { export interface Url { protocol?: string; hostname?: string; pathname?: string; } export function parse(urlStr: string, parseQueryString?, slashesDenoteHost?): Url; } declare module "path" { export function normalize(p: string): string; export function join(...paths: any[]): string; export var sep: string; } ``` now `/// ` `node.d.ts`and then perform the `import url = require("url");` or `import * as URL from "url"`to load the module. ```ts /// import * as URL from "url"; let myUrl = URL.parse("http://www.typescriptlang.org"); ``` ### Shorthand ambient modules If you don't write a declaration before using a new module, you can use a shorthand declaration to get started quickly. ##### declarations.d.ts ```ts declare module "hot-new-module"; ``` All imports from the shorthand module are `any` It has a type. ```ts import x, {y} from "hot-new-module"; x(y); ``` ### Wildcard module declarations [SystemJS](https://github.com/systemjs/systemjs/blob/master/docs/overview.md#plugin-syntax)I [AMD](https://github.com/amdjs/amdjs-api/blob/master/LoaderPlugins.md)Module loaders such as can import non-JavaScript content. Both typically use prefixes or suffixes to indicate special loading meanings. To deal with these cases, you can use wildcard module declarations. ```ts declare module "*!text" { const content: string; export default content; } // 일부는 다른 방법으로 사용합니다. declare module "json!*" { const value: any; export default value; } ``` now `"*!text"` I `"json!*"`You can import the ones that match the ```ts import fileContent from "./xyz.txt!text"; import data from "json!http://example.com/data.json"; console.log(data, fileContent); ``` ### UMD modules Some libraries are used by many module loaders, or are designed to be used without module loading (global variables). This can be called [UMD](https://github.com/umdjs/umd) It's called a module. These libraries can be accessed through import or global variables. Like what: ##### math-lib.d.ts ```ts export function isPrime(x: number): boolean; export as namespace mathLib; ``` Libraries can be used as imports within modules: ```ts import { isPrime } from "math-lib"; isPrime(2); mathLib.isPrime(2); // 오류: 모듈 내부에서 전역 정의를 사용할 수 없습니다. ``` It can also be used as a global variable, but only within a script. (The script is a file that does not have imports or exports.) ```ts mathLib.isPrime(2); ``` # Guidance for structuring modules ## Export as close to top-level as possible There should be as little friction as possible when the user of the module uses the export module. Adding too many levels of overlap tends to make them unwieldy, so you need to think carefully about how you structure them. Exporting namespaces in a module is an example of adding too many nested layers. Namespaces sometimes have their uses, but when you use the module, you add an additional level of indirection. This can quickly become a painful point for the user, and is usually unnecessary. I have a similar problem with the static method of the class that I exported - it adds a nested layer to the class itself. Consider simply exporting helper functions unless you want to elevate the wording or intent in a clearly useful way. ### unity `class`I `function`If you want to export, `export default`(If you're only exporting a single `class` or `function`, use `export default`) Just as "top-level export" reduces friction for module users, so does the introduction of default export. If the main purpose of the module is to store one specific export, consider exporting as the default export. This makes it easier to import and actually use import. Like what: #### MyClass.ts ```ts export default class SomeType { constructor() { ... } } ``` #### MyFunc.ts ```ts export default function getThing() { return "thing"; } ``` #### Consumer.ts ```ts import t from "./MyClass"; import f from "./MyFunc"; let x = new t(); console.log(f()); ``` This is optimal for users. The name you want for the type (in this case, the name `t`) and doesn't need to over-dot to find the object. ### If you're exporting multiple objects, put them all at top-level #### MyThings.ts ```ts export class SomeType { /* ... */ } export function someFunc() { /* ... */ } ``` When importing on the contrary: ### Explicitly list imported names #### Consumer.ts ```ts import { SomeType, someFunc } from "./MyThings"; let x = new SomeType(); let y = someFunc(); ``` ### Use the namespace import pattern if you're importing a large number of things #### MyLargeModule.ts ```ts export class Dog { ... } export class Cat { ... } export class Tree { ... } export class Flower { ... } ``` #### Consumer.ts ```ts import * as myLargeModule from "./MyLargeModule.ts"; let x = new myLargeModule.Dog(); ``` ## Re-export to extend Often it is necessary to expand the functionality of the module. The general JS pattern is similar to how the JQuery extension works. _extensions_to augment an existing object. As mentioned earlier, modules are like global namespace objects, such as _merge_ Don't. The recommended method here is to change the existing object to the _Without deformation_ The new functionality is to export the object. `Calculator.ts` Consider a simple calculator implementation defined in a module. This module also passes a list of input strings and creates a helper function that allows you to test the functionality of the calculator by writing the export results. #### Calculator.ts ```ts export class Calculator { private current = 0; private memory = 0; private operator: string; protected processDigit(digit: string, currentValue: number) { if (digit >= "0" && digit <= "9") { return currentValue * 10 + (digit.charCodeAt(0) - "0".charCodeAt(0)); } } protected processOperator(operator: string) { if (["+", "-", "*", "/"].indexOf(operator) >= 0) { return operator; } } protected evaluateOperator(operator: string, left: number, right: number): number { switch (this.operator) { case "+": return left + right; case "-": return left - right; case "*": return left * right; case "/": return left / right; } } private evaluate() { if (this.operator) { this.memory = this.evaluateOperator(this.operator, this.memory, this.current); } else { this.memory = this.current; } this.current = 0; } public handleChar(char: string) { if (char === "=") { this.evaluate(); return; } else { let value = this.processDigit(char, this.current); if (value !== undefined) { this.current = value; return; } else { let value = this.processOperator(char); if (value !== undefined) { this.evaluate(); this.operator = value; return; } } } throw new Error(`Unsupported input: '${char}'`); } public getResult() { return this.memory; } } export function test(c: Calculator, input: string) { for (let i = 0; i < input.length; i++) { c.handleChar(input[i]); } console.log(`result of '${input}' is '${c.getResult()}'`); } ``` Exposed `test` This is a simple calculator test that uses a function. #### TestCalculator.ts ```ts import { Calculator, test } from "./Calculator"; let c = new Calculator(); test(c, "1+2*33/11="); // 9 출력 ``` Inherit this so that you can enter a number other than 10. `ProgrammerCalculator.ts`Let's make it. #### ProgrammerCalculator.ts ```ts import { Calculator } from "./Calculator"; class ProgrammerCalculator extends Calculator { static digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"]; constructor(public base: number) { super(); const maxBase = ProgrammerCalculator.digits.length; if (base <= 0 || base > maxBase) { throw new Error(`base has to be within 0 to ${maxBase} inclusive.`); } } protected processDigit(digit: string, currentValue: number) { if (ProgrammerCalculator.digits.indexOf(digit) >= 0) { return currentValue * this.base + ProgrammerCalculator.digits.indexOf(digit); } } } // 새로 상속된 calculator를 Calculator로 export 하기 export { ProgrammerCalculator as Calculator }; // 또한 헬퍼 함수도 export 하기 export { test } from "./Calculator"; ``` New `ProgrammerCalculator` The module is `Calculator` It exports an API similar to a module, but does not augment the objects of the original module. Here is the test for the ProgrammerCalculator class: #### TestProgrammerCalculator.ts ```ts import { Calculator, test } from "./ProgrammerCalculator"; let c = new Calculator(2); test(c, "001+010="); // 3 출력 ``` ## Do not use namespaces in modules When you first apply a module-based configuration, you typically tend to wrap exports in an additional namespace layer. The module has its own scope, and only exported declarations are visible outside the module. With this in mind, namespaces rarely change values when dealing with modules. On the front of the configuration, namespaces are convenient for grouping logically related objects and types into a global scope. For example, in C#, you can find all collection types in System.Collections. By organizing types into hierarchical namespaces, users of those types have a good experience of "discovery". On the other hand, a module must already exist in the file system. To interpret paths and file names, you can use a logical construction scheme. You can use the /collections/generic/ folder with the list module. Namespaces are important to avoid naming conflicts in the global scope. For example `My.Application.Customer.AddForm`and `My.Application.Order.AddForm` -- Both types have the same name, but have different namespaces. However, this is not a problem in the module. There is no reason why two objects within a module should have the same name. In terms of usage, the user of a particular module chooses the name to use to refer to the module, so accidental name conflicts are not possible. > For more information about modules and namespaces, see [Namespaces and Modules](./namespaces-and-modules.md)Please refer to ## Red Flags The following are all red flags for module structuring: If any of the following applies to the file, double-check that you haven't attempted to create a namespace for the external module: - Only top-level declarations `export namespace Foo { ... }`In file (`Foo`and move everything to the 'higher' level) - Same as top-level position `export namespace Foo {`Multiple files with a single `Foo`Don't think it's going to be combined!)
Translation of Project References.md * * * title: Project References layout: docs permalink: /ko/docs/handbook/project-references.html oneline: How to split up a large TypeScript project ## translatable: true Project Reference is a new feature in TypeScript 3.0 that allows you to organize TypeScript programs into smaller pieces. This greatly improves build times and enforces logical separation between components, allowing you to organize your code in a new and better way. It also works with project references for quick TypeScript builds. `tsc` The new mode of `--build` Flags have been introduced. # An Example Project Let's take a look at some pretty common programs and see how a project reference can help you better organize them. `converter`and `units`Let's imagine that there are two modules in a project, and each module has a corresponding test file: ```shell /src/converter.ts /src/units.ts /test/converter-tests.ts /test/units-tests.ts /tsconfig.json ``` The test file is imported into the implementation file and the test is carried out: ```ts // converter-tests.ts import * as converter from "../converter"; assert.areEqual(converter.celsiusToFahrenheit(0), 32); ``` Previously, this structure behaved awkwardly if you used a single tsconfig file: - It is possible to import test files from the implementation file - I probably didn't want to. `src`does not appear in the output folder name. `test`and `src`It is not possible to build them at the same time - Inside the implementation file _Contents_ It will never raise a new error, but it will never cause a new error for the test file. _Type Inspection_You will need to redo it - Changing only the test file does not change anything, but you need to re-check the type of implementation file Using multiple tsconfig files to solve one of these problems _Some_This can be solved, but a new problem arises: - Since there is no built-in up-to-date inspection, it is always `tsc`must be run twice - `tsc`Calling twice incurs more startup time overhead - `tsc-w`cannot run multiple config files at once A project reference can solve all of these problems. # What are the project references? (What is a Project Reference?) `tsconfig.json` The file has a new top-level property `reference`It has. This is an array of objects that specify the project to be referenced: ```js { "compilerOptions": { // The usual }, "references": [ { "path": "../src" } ] } ``` Each reference's `path` The property is `tsconfig.json` Point to the directory where the file is located, or to the config file itself (which can have any name). When you refer to a project, something new happens: - If you import a module from a referenced project, you can use the module's _output_ Load the declaration file instead (`.d.ts`) - If the referenced project is `outFile`When you create an output file `.d.ts` The declaration of the file is exposed within this project - The build mode (shown below) automatically builds the referenced project if necessary Separating into multiple projects greatly improves type checking and compilation speeds, reduces memory usage when using the editor, and improves logical grouping of programs. # `composite` The referenced project must be a new `composite` The setting must be enabled. This setting is necessary so that TypeScript can quickly determine where to find the output of the referenced project. `composite` When you enable the flag, a few things change: - What if `rootDir` If the setting is not explicitly specified, the default value is `tsconfig` The directory where the file is located - All implementation files must be `include` Fits the pattern or `files` It must be inside an array. If this constraint is violated, `tsc`tells you which files are not specified - `declaration`must be turned on # `declarationMap`s [Declaration Source Map](https://github.com/Microsoft/TypeScript/issues/14479)We've also added support for What if `--declarationMap`, you can use editor features such as "Go to Definition" and rename to transparently navigate in supported editors and modify code across project boundaries. # `prepend`and `outFile` (`prepend` with `outFile`) In the reference `prepend` You can enable the appending of dependencies using the options: ```js "references": [ { "path": "../utils", "prepend": true } ] ``` Adding a project includes the output of the project on top of the output of the current project. This is because `.js` Files `.d.ts` All of them work in the file, and the source map file is also released correctly. `tsc`uses only existing files on disk for this task, so that the output of a project may appear more than once in the resulting file, making it possible to create a project in which the correct output file cannot be generated. For example: ```txt A ^ ^ / \ B C ^ ^ \ / D ``` In this situation, it is important not to add to each reference, because `D`On the output of the `A`This is because two copies of the - which can lead to unforeseen consequences. # Caveats for Project References There are a few trade-offs that you should be aware of when it comes to project references. Because a dependency project is built from a dependency `.d.ts` Because it uses files, you can inspect certain build output before you can browse through the project without seeing incorrect errors in the editor. _or_ After cloning, you must build the project. We are working on a .d.ts creation process that can improve this, but for now, we recommend that developers build after cloning. Additionally, to maintain compatibility with existing build workflows, `tsc`The `--build` Unless you call the switch, it does not automatically build dependencies _Is_. `--build`Let's learn about. # Build Mode for TypeScript The long-awaited feature is a smart incremental build for TypeScript projects. In 3.0 `tsc`In `--build` Flags are now available. This behaves more like a build manager than a simple compiler. `tsc`It is a new entry point for . `tsc --build` (The abbreviated form is `tsc -b`) to do the following: - Locate all referenced projects - Detect if it's up-to-date - Build projects that are not up-to-date in the correct order `tsc -b`You can provide multiple config file paths to (for example. `tsc -b src test`). `tsc -p`Like, if the config file name is `tsconfig.json`If so, you don't need to specify a name. ## `tsc -b` The command-line (`tsc -b` Commandline) You can specify as many config files as you want: ```shell > tsc -b # 현재 디렉터리에 있는 tsconfig.json 사용 > tsc -b src # src/tsconfig.json 사용 > tsc -b foo/prd.tsconfig.json bar # foo/prd.tsconfig.json 와 bar/tsconfig.json 사용 ``` Don't worry about the order of the files you pass to the command line - if you need them `tsc`Because the dependencies are rearranged, the dependencies are always built first. `tsc -b`There are a few more flags that can be specified: - `--verbose`: Displays a detailed log of how it is going (can be combined with other flags) - `--dry`: It doesn't actually build, but it shows how it will work - `--clean`: Removes the output of the specified project (`--dry`It can be combined with) - `--force`: All projects behave as if they are not up to date - `--watch`: Surveillance mode (`--verbose`It cannot be combined with any other flags except ) # Precautions (Caveats) generally `tsc`The `noEmitOnError`If is not enabled, the output (`.js`and `.d.ts`) to create a . It's very bad to do this in an incremental build system - because if one of the dependencies is not up-to-date, it will skip building the project that is currently up-to-date in the next build. _once_ You can only see it. For this reason, `tsc -b`The `noEmitOnError`behaves as effectively as if it were enabled in all projects. There is no build output (`.js`, `.d.ts`, `.d.ts.map`, etc.), depending on whether the source control tool preserves the timestamp between the local and remote copies, after a specific source control operation. `--force` You may need to run the build. # MSBuild If you have an MSBuild project, add the following to the build mode to the proj file: ```xml true ``` You can activate it. This enables automatic incremental builds as well as removal. `tsconfig.json` / `-p`Note that existing TypeScript project properties are not taken into account - all settings must be managed using a tsconfig file. Some teams have projects where tsconfig files are managed in parallel, such as _Implicit_ It has graph order and has set up an MSBuild-based workflow. If the solution is like this, please use the project reference with `msbuild`Raise `tsc -p`You can continue to use it with; They are fully interoperable. # Guidance ## Overall Structure More `tsconfig.json` files, to centrally control common compiler options. [Inheriting configuration files](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html)You'll want to use it. In this way, you can change the settings in one file without modifying multiple files. Another good way to do this is to simply add all leaf-node projects to `references`Have a `files`"Solution" to set to an empty array `tsconfig.json` It's about having a file (otherwise the file will be compiled twice because of the solution file). Starting with 3.0, at least one `reference`price `tsconfig.json`If you are in, empty `files` Note that having arrays is no longer an error. This provides a simple entry point; For example, in the TypeScript repository, `src/tsconfig.json` Simply because it lists all the subprojects inside `tsc -b src` Run to build all the endpoints. These patterns can be seen in the TypeScript repository - as the main example `src/tsconfig_base.json`, `src/tsconfig.json`and `src/tsc/tsconfig.json`Take a look. ## Structuring for relative modules In general, switching repositories using relative modules doesn't require much else. Simply use the parent folder of the `tsconfig.json` Place the file within each subdirectory, and ensure that it matches the intended hierarchy of the program. `reference`to this config file. `outDir`as an explicit subfolder of the output folder, or `rootDir`as the common root of all project folders. ## Structuring for outFiles `outFile`The layout of compilation with is more flexible because relative paths don't matter much. One thing to remember is that until the "last" project, `prepend`- which will improve build time and reduce the number of I/Os required for a given build. The TypeScript repository itself is a good reference here - there are several "library" projects and "endpoint" projects; The "endpoint" project is kept as small as possible and only pulls the libraries that are needed.
Translation of More on Functions.md * * * title: More on Functions layout: docs permalink: /ko/docs/handbook/2/functions.html ## oneline: "Let's see how functions work in TypeScript." Whether it's a local function, a function loaded from another module, or a method of any class, a function is a fundamental component of any application. A function is a value. And just like any value, there are many ways to describe how functions can be called in TypeScript. Let's see how to write types that describe functions. ## Function type expressions The simplest way to describe a function is to use the _Function type expressions_ Is. This type is grammatically similar to the arrow function. ```ts twoslash function greeter(fn: (a: string) => void) { fn("Hello, World"); } function printToConsole(s: string) { console.log(s); } greeter(printToConsole); ``` `(a: string) => void` The syntax is "string type `a`as one parameter and has no return value". Like a function declaration, if the parameter is not typed, it is implicitly `any`becomes. > If the parameter name is **essential** Keep in mind that. Function type `(string) => void`The "`any` With type `string`It means a function with a parameter named ! Of course, you can use a type alias to name a function's type. ```ts twoslash type GreetFunction = (a: string) => void; function greeter(fn: GreetFunction) { // ... } ``` ## Call Signature In JavaScript, functions can not only be called, but they can also have properties. However, the function-type expression syntax does not allow you to define properties. If we try to describe something that is callable and has properties, then the object type must be _Call Signature_ can be expressed using . ```ts twoslash type DescribableFunction = { description: string; (someArg: number): boolean; }; function doSomething(fn: DescribableFunction) { console.log(fn.description + " returned " + fn(6)); } ``` This syntax is different from function-type expressions. Between the type of the parameter and the type of the return value `=>`Rather than `:`should be used. ## Configuration Signatures The JavaScript function is `new`It can also be called through operators. TypeScript uses these things mainly to create new objects. _constructor_ It is considered to be. You must display the call signature in front of the `new` By attaching keywords, _Configuration Signatures_You can write. ```ts twoslash type SomeObject = any; // ---cut--- type SomeConstructor = { new (s: string): SomeObject; }; function fn(ctor: SomeConstructor) { return new ctor("hello"); } ``` JavaScript `Date` Some objects, such as objects, are `new`It can be called with or without . You can combine call signatures and configuration signatures in the same type at will. ```ts twoslash interface CallOrConstruct { new (s: string): Date; (n?: number): number; } ``` ## Generic functions It is not uncommon to write a function in which the input value is related to the type of the output value, or the types of the two inputs are related to each other. Let's consider for a moment a function that returns the first element of an array. ```ts twoslash function firstElement(arr: any[]) { return arr[0]; } ``` The function does its job, but unfortunately the return type is `any` Is. It would be better if the function returned the type of the array element. In TypeScript: _Generic_ Syntax is used to express the correlation between two values. We use the function signature _Type Parameters_You can do that by declaring. ```ts twoslash function firstElement(arr: Type[]): Type | undefined { return arr[0]; } ``` Type Parameters `Type`to this function, and by using it in two places where it is needed, we have created a link between the input value (array) and the output (return value) of the function. Now, when we call this function, we get a clearer type. ```ts twoslash declare function firstElement(arr: Type[]): Type | undefined; // ---cut--- // s는 "string" 타입 const s = firstElement(["a", "b", "c"]); // n은 "number" 타입 const n = firstElement([1, 2, 3]); // u는 "undefined" 타입 const u = firstElement([]); ``` ### Inference In this example, we use `Type`Note that it is not specified. where the type is _It was deduced_ In other words, it is automatically selected by TypeScript. We can also use multiple type parameters. For example, `map`The standalone version of should look like this: ```ts twoslash // prettier-ignore function map(arr: Input[], func: (arg: Input) => Output): Output[] { return arr.map(func); } // 매개변수 'n'의 타입은 'string' 입니다. // 'parsed'는 number[] 타입을 하고 있습니다. const parsed = map(["1", "2", "3"], (n) => parseInt(n)); ``` In this example, TypeScript uses the `Input` Type and (given as input `string` from the array) `Output`Type the return value of the function expression (`number`) can be inferred from the ### Type Constraints We are _all_ We have written generic functions that operate on types. Sometimes, we want to associate two values, but only for a subset of them. In these cases, we use _Type Constraints_to limit the types that the type parameter can accept. Let's write a function that returns the longer of the two values. For this task, you can use the number of `length` Properties are required. `extends`Using a clause, the type parameter is changed to that type _restriction_ I can. ```ts twoslash // @errors: 2345 2322 function longest(a: Type, b: Type) { if (a.length >= b.length) { return a; } else { return b; } } // longerArray 의 타입은 'number[]' 입니다' const longerArray = longest([1, 2], [1, 2, 3]); // longerString 의 타입은 'alice' | 'bob' 입니다. const longerString = longest("alice", "bob"); // 에러! Number에는 'length' 프로퍼티가 없습니다. const notOK = longest(10, 100); ``` In this example, there are a few interesting points to note. We believe that TypeScript is `longest`The return type of _inference_ I allowed it to be. Return type inference also works with generic functions. We `Type`Rewrite `{ length: number }`As limited to, we `a`and `b` About the parameters `.length` I was able to access the property. If there were no type restrictions, these values would not have access to the property because they could be of any other type that did not have the length property. `longerArray`and `longerString`The type of was inferred based on the arguments. It's important to remember that generics are when two or more values are associated with the same type! In the end, as we want `longest(10,100)`silver `number`Type `.length` You can see that the call was rejected because you didn't have any properties. ### Working with limited values The following are common mistakes when using generic-type constraints: ```ts twoslash // @errors: 2322 function minimumLength( obj: Type, minimum: number ): Type { if (obj.length >= minimum) { return obj; } else { return { length: minimum }; } } ``` This function doesn't seem to be a problem. `Type`silver `{ length: number }`, and the function is `Type`or a value that satisfies that constraint. The problem is that this function satisfies the constraints. _How_ Not an object, but an input _How_ It returns an object. If this code is valid, you can write the following code that will definitely not work. ```ts twoslash declare function minimumLength( obj: Type, minimum: number ): Type; // ---cut--- // 'arr' gets value { length: 6 } const arr = minimumLength([1, 2, 3], 6); // 여기서 배열은 'slice' 메서드를 가지고 있지만 // 반환된 객체는 그렇지 않기에 에러가 발생합니다! console.log(arr.slice(0)); ``` ### Specifying Type Arguments TypeScript usually deduces the intended type from a generic call, but this is not always the case. For example, let's say you have written a function that combines two arrays. ```ts twoslash function combine(arr1: Type[], arr2: Type[]): Type[] { return arr1.concat(arr2); } ``` In general, it would be wrong to call that function with an unmatched array. ```ts twoslash // @errors: 2322 declare function combine(arr1: Type[], arr2: Type[]): Type[]; // ---cut--- const arr = combine([1, 2, 3], ["hello"]); ``` If you intend to do this, you can do it manually `Type`must be stated. ```ts twoslash declare function combine(arr1: Type[], arr2: Type[]): Type[]; // ---cut--- const arr = combine([1, 2, 3], ["hello"]); ``` ### Guidelines for writing good generic functions It's fun to write a generic function, and it can be easy to use type parameters. Using too many type parameters or constraints where they are not strictly necessary can lead to poor reasoning and frustration with your function callers. #### Pressing the type parameter Here's how to write two functions that look similar. ```ts twoslash function firstElement1(arr: Type[]) { return arr[0]; } function firstElement2(arr: Type) { return arr[0]; } // a: number (good) const a = firstElement1([1, 2, 3]); // b: any (bad) const b = firstElement2([1, 2, 3]); ``` At first glance, it may look the same, `firstElement1`This is a better way to write this function. The deferred return type of this function is `Type` However, `firstElement2`The inferred return type of is at the time of the call, rather than "waiting" for TypeScript to interpret the type during the call. `arr[0]` Because the expression is interpreted using type constraints, `any`becomes. > **rule**: If possible, use the type parameters themselves rather than constraining them. #### Using fewer type parameters Here is another pair of similar functions: ```ts twoslash function filter1(arr: Type[], func: (arg: Type) => boolean): Type[] { return arr.filter(func); } function filter2 boolean>( arr: Type[], func: Func ): Type[] { return arr.filter(func); } ``` We are _You don't associate two values._ Type Parameters `Func`I created it. This is quite bad, because the caller who wants the type argument has to provide additional type arguments for no reason. `Func`will only make the function harder to read and understand, it will do nothing! > **rule**: Always use the minimum type parameters if possible #### The type parameter must appear twice. Sometimes we overlook the fact that functions may not need generics. ```ts twoslash function greet(s: Str) { console.log("Hello, " + s); } greet("world"); ``` We could have easily written a simple version. ```ts twoslash function greet(s: string) { console.log("Hello, " + s); } ``` The type parameter is _Associating multiple value types_Please remember that it is used for the purpose of doing. If a type parameter is used only once in a function signature, it is not associated with anything. > **rule**: If the type parameter appears in only one place, think again about whether it is really necessary. ## Optional Parameters Functions in JavaScript often use a variable number of arguments. For example, `number`of `toFixed` The method optionally uses digits. ```ts twoslash function f(n: number) { console.log(n.toFixed()); // 0 arguments console.log(n.toFixed(3)); // 1 argument } ``` In TypeScript, we use the parameter to `?`By marking it as _Optional_It can be made with ```ts twoslash function f(x?: number) { // ... } f(); // OK f(10); // OK ``` If the type of parameter is `number`, but not specified in JavaScript, the parameter is `undefined`Because it becomes, `x` The parameters are substantially `number | undefined` It will be a type. You can use the parameters _Default_We can also provide. ```ts twoslash function f(x = 10) { // ... } ``` now `f`Within the body of all `undefined` Argument `10`Because it is replaced by `x`The type of is `number`It will be. When the parameter is optional, the caller `undefined`, mimicking the "missing" argument. ```ts twoslash declare function f(x?: number): void; // cut // All OK f(); f(10); f(undefined); ``` ### Optional parameters in callback functions Once you know about optional parameters and function type expressions, it's easy to make the following mistakes when writing a function that invokes callbacks. ```ts twoslash function myForEach(arr: any[], callback: (arg: any, index?: number) => void) { for (let i = 0; i < arr.length; i++) { callback(arr[i], i); } } ``` People `index?`is usually intended to be used as an optional parameter, and you want both calls to be valid. ```ts twoslash // @errors: 2532 declare function myForEach( arr: any[], callback: (arg: any, index?: number) => void ): void; // ---cut--- myForEach([1, 2, 3], (a) => console.log(a)); myForEach([1, 2, 3], (a, i) => console.log(a, i)); ``` _indeed_ What this means is that _`callback`Can be called with this one argument_ Is. In other words, the previous function definition is like saying that the implementation might look like this: ```ts twoslash // @errors: 2532 function myForEach(arr: any[], callback: (arg: any, index?: number) => void) { for (let i = 0; i < arr.length; i++) { // 오늘은 index를 제공하고 싶지 않아 callback(arr[i]); } } ``` Eventually, TypeScript enforces this semantics, resulting in errors that wouldn't actually happen. ```ts twoslash // @errors: 2532 declare function myForEach( arr: any[], callback: (arg: any, index?: number) => void ): void; // ---cut--- myForEach([1, 2, 3], (a, i) => { console.log(i.toFixed()); }); ``` In JavaScript, if a call is made with more arguments than specified by the parameter, the remaining arguments are simply ignored. TypeScript behaves the same way. A function with fewer parameters (with the same type) can replace a function with more parameters. > When you write a function type for a callback, you can use the _Call_ Unless there is an intent, _never_ Do not use optional parameters. ## Function Overload Some JavaScript functions can be called with varying numbers and types of arguments. For example, you can use `Date`and take one timestamp (one argument), or you can create a function that takes month/day/year format (three arguments). In TypeScript, we have a function that can be called in different ways. _Overlord Signature_It can be described as writing. To do this, you need to write down a few function signatures (usually two or more) and then write the function body. ```ts twoslash // @errors: 2575 function makeDate(timestamp: number): Date; function makeDate(m: number, d: number, y: number): Date; function makeDate(mOrTimestamp: number, d?: number, y?: number): Date { if (d !== undefined && y !== undefined) { return new Date(y, mOrTimestamp, d); } else { return new Date(mOrTimestamp); } } const d1 = makeDate(12345678); const d2 = makeDate(5, 5, 5); const d3 = makeDate(1, 3); ``` In this example, we have created two overloads. One receives one argument, the other receives three arguments. These two signatures from the beginning _Overlord Signature_ It is called. Then, we wrote a function implementation with a compatible signature. The function is _Implement_ It has a signature, but it cannot be called directly. Although we have created two optional parameters after the required parameters, we cannot call this function with only two parameters! ### Overlord Signatures and Implementation Signatures This is a common source of confusion. People often write code like the one below, and don't understand why there is an error. ```ts twoslash // @errors: 2554 function fn(x: string): void; function fn() { // ... } // 0개의 인자로 호출하기를 예상했음 fn(); ``` Again, the signature used to write the function body is "invisible" from the outside. > _Implement_The signature of is invisible from the outside. > When you write an overloaded function, you can use the _More than one_You must write the signature of the function on top of the function implementation. In addition, the implementation signature is an overloaded signature and _Must be compatible_ The. For example, the following functions are erroneous because the implementation signature does not correctly match the overloads. ```ts twoslash // @errors: 2394 function fn(x: boolean): void; // 인수 타입이 옳지 않습니다. function fn(x: string): void; function fn(x: boolean) {} ``` ```ts twoslash // @errors: 2394 function fn(x: string): string; // 반환 타입이 옳지 않습니다. function fn(x: number): boolean; function fn(x: string | number) { return "oops"; } ``` ### Writing a good overload As with generics, there are some guidelines to follow when writing function overloads. Following these rules will make your functions easier to call, easier to understand, and easier to implement. Consider a function that returns the length of a string or array. ```ts twoslash function len(s: string): number; function len(arr: any[]): number; function len(x: any) { return x.length; } ``` This function is fine. We can call this function through a string or an array. However, since TypeScript only interprets a function through one overload, we can use this function as a string _or_ It cannot be called through values that can be arrays. ```ts twoslash // @errors: 2769 declare function len(s: string): number; declare function len(arr: any[]): number; // ---cut--- len(""); // OK len([0]); // OK len(Math.random() > 0.5 ? "hello" : [0]); ``` Since both overloads have the same number of arguments and the same return type, we can write the following in the form of an unoverloaded function: ```ts twoslash function len(x: any[] | string) { return x.length; } ``` Much better! The caller can call this function with one of two values, eliminating the need to find an additional exact implementation signature. > If possible, use the union type instead of overload ### Within the function `this` To declare TypeScript uses the `this`What should be, we deduce through code flow analysis, as shown in the example below. ```ts twoslash const user = { id: 123, admin: false, becomeAdmin: function () { this.admin = true; }, }; ``` TypeScript functions `user.becomeAdmin`This external object `user`Equivalent to `this`I understand that it has. Usually this may be enough, but you guys `this`You'll often need more control over what objects represent. In the JavaScript specification, `this`Since it says that you can't have a parameter named ", TypeScript uses that grammar space in the body of the function `this`Allows it to be used to define the type of . ```ts twoslash interface User { id: number; admin: boolean; } declare const getDB: () => DB; // ---cut--- interface DB { filterUsers(filter: (this: User) => boolean): User[]; } const db = getDB(); const admins = db.filterUsers(function (this: User) { return this.admin; }); ``` This pattern is commonly used in callback-style APIs, which control when other objects call a function. In order to achieve this effect, it is necessary to use a non-arrow function. `function` You must use keywords. ```ts twoslash // @errors: 7041 7017 interface User { id: number; isAdmin: boolean; } declare const getDB: () => DB; // ---cut--- interface DB { filterUsers(filter: (this: User) => boolean): User[]; } const db = getDB(); const admins = db.filterUsers(() => this.admin); ``` ## Other types to know about When working with function types, there are a few additional types that appear frequently. Like all types, you can use them anywhere, but they're especially relevant in the context of functions. ### `void` `void`means the return value of a function that does not return a value. In the function `return`When there is no statement, or when it does not explicitly return a value, it is the type that is deduced. ```ts twoslash // 추론된 반환 타입은 void 입니다. function noop() { return; } ``` In JavaScript, a function that returns nothing is implicitly `undefined` Returns a value. But in TypeScript, `void`and `undefined`is not considered the same. We'll go into more detail at the end of this chapter. > `void`The `undefined`It is not the same as. ### `object` Special type `object`is the raw value (`string`, `number`, `bigint`, `boolean`, `symbol`, `null`, `undefined`) to any value that is not This is _Empty object type_ `{ }`It is different from the global type `Object`It is also different from . Perhaps you `Object`You won't be able to use it. > `object`The `Object`It's not. **All the time** `object`Use it! In JavaScript, the value of a function is an object. There are properties, and in the prototype chain `Object.prototype`There is, `instanceof Object`In the meantime, `Object.keys`and so on. For this reason, in TypeScript, the function type is `object`It is considered as. ### `unknown` `unknown` The type is _All values_Indicates the `any` It is similar to the type, `unknown` It is safer because it is not valid to substitute something for the type. ```ts twoslash // @errors: 2571 function f1(a: any) { a.b(); // OK } function f2(a: unknown) { a.b(); } ``` This is because `any` It is useful for describing function types because it is possible to express a function that accepts any value without using the value of the form in the body of the function. Conversely, you can represent a function that returns a value of type unknown. ```ts twoslash declare const someRandomString: string; // ---cut--- function safeParse(s: string): unknown { return JSON.parse(s); } // 'obj'를 사용할 때 조심해야 합니다! const obj = safeParse(someRandomString); ``` ### `never` What functions are _Never_ It does not return a value ```ts twoslash function fail(msg: string): never { throw new Error(msg); } ``` `never` Type means a value that can never be observed. In return type, it means that the function throws an exception or terminates program execution. `never`also appears when TypeScript determines that there is nothing left in the union. ```ts twoslash function fn(x: string | number) { if (typeof x === "string") { // do something } else if (typeof x === "number") { // do something else } else { x; // 'never' 타입이 됨! } } ``` ### `Function` Global Types `Function`silver `bind`, `call`, `apply` It is also used to describe other properties in JavaScript function values. In addition, this includes `Function`The value of the type has a value that can always be called, and these calls are `any`Returns . ```ts twoslash function doSomething(f: Function) { return f(1, 2, 3); } ``` This is because _Call an untyped function_ It is unsafe and unsafe `any` It's generally best to avoid them because they return the type. If you need to allow an arbitrary function, but you don't want to call it, `() => void` The type is generally safer. ## The remaining parameters and arguments

배경지식 읽기:
나머지 매개변수(Rest Parameter)
전개 구문(Spread Syntax)

### Rest Parameter We can use optional parameters and overloads to accept a variety of fixed arguments, but we can use _Undefined_ A function that accepts a number argument _The rest of the parameters_It can be defined using . The rest of the parameters appear after all other parameters, `...` Use syntax. ```ts twoslash function multiply(n: number, ...m: number[]) { return m.map((x) => n * x); } // 'a' gets value [10, 20, 30, 40] const a = multiply(10, 1, 2, 3, 4); ``` In TypeScript, the type notation for these parameters is implicitly `any`Rather than `any[]`, and the type expression is `Array` or `T[]` Or it should be expressed in tuple type (which we will learn later). ### Rest Argument Conversely, we use the deployment syntax to determine the number of arguments supplied by an array to _offer_I can. For example, the array's `push` A method can take any number of arguments. ```ts twoslash const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; arr1.push(...arr2); ``` In general, TypeScript does not consider arrays to be immutable. This can cause the following surprising behavior: ```ts twoslash // @errors: 2556 // 추론된 타입은 0개 이상의 숫자를 가지는 배열인 number[] // 명시적으로 2개의 숫자를 가지는 배열로 간주되지 않습니다 const args = [8, 5]; const angle = Math.atan2(...args); ``` The best solution to this situation depends on the code, but in general, `const` Context is the simplest solution. ```ts twoslash // 길이가 2인 튜플로 추론됨 const args = [8, 5] as const; // OK const angle = Math.atan2(...args); ``` Using the remaining arguments is important when targeting older runtimes, [`downlevelIteration`](/tsconfig#downlevelIteration)You may need to. ## Parameter Destruction

배경지식 읽기:
구조분해 할당

Parameter decomposition can be used to conveniently unpack an object provided as an argument into one or more local variables in the body of the function. In JavaScript, it looks like this: ```js function sum({ a, b, c }) { console.log(a + b + c); } sum({ a: 10, b: 3, c: 9 }); ``` The type notation for the object is located after the decomposition syntax. ```ts twoslash function sum({ a, b, c }: { a: number; b: number; c: number }) { console.log(a + b + c); } ``` It may seem a bit verbose, but you can use the named type here as well. ```ts twoslash // 이전 예제와 동일 type ABC = { a: number; b: number; c: number }; function sum({ a, b, c }: ABC) { console.log(a + b + c); } ``` ## Assignability of functions ### `void` Return Type hydrous `void` Return types can cause some uncommon but predictable behavior. `void` Contextual typing with return types returns nothing to the function **Avoid** Not forced **Is**Another way to explain this is, `void` A contextual function type with a return type (`type vf = () => void`) is implemented, _No value_or may be returned, but will be ignored. Therefore, the type to be described later `() => void`All implementations are valid. ```ts twoslash type voidFunc = () => void; const f1: voidFunc = () => { return true; }; const f2: voidFunc = () => true; const f3: voidFunc = function () { return true; }; ``` And when the return values of these functions are assigned to other variables, they are still `void`We will keep the type. ```ts twoslash type voidFunc = () => void; const f1: voidFunc = () => { return true; }; const f2: voidFunc = () => true; const f3: voidFunc = function () { return true; }; // ---cut--- const v1 = f1(); const v2 = f2(); const v3 = f3(); ``` Since such behavior exists, `Array.prototype.push`returns a number, `Array.prototype.forEach` Method `void` Even if you expect a function with a return type, the following code may be valid: ```ts twoslash const src = [1, 2, 3]; const dst = [0]; src.forEach((el) => dst.push(el)); ``` There is one other case to keep in mind. If the literal function definition is `void` If it has a return value, the function must return nothing. **Not**. ```ts twoslash function f2(): void { // @ts-expect-error return true; } const f3 = function (): void { // @ts-expect-error return true; }; ``` `void`For more information, refer to the following article topics. - [v1 handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html#void) - [v2 handbook](https://www.typescriptlang.org/docs/handbook/2/functions.html#void) - [FAQ - "Why are functions returning non-void assignable to function returning void?"](https://github.com/Microsoft/TypeScript/wiki/FAQ#why-are-functions-returning-non-void-assignable-to-function-returning-void)

Generated by :no_entry_sign: dangerJS against 9d86fb2ba8c4d648c36959bb5076bb71ae42e4f9

yusunghyun commented 1 year ago

@microsoft-github-policy-service agree

dvlprsh commented 1 year ago

LGTM

github-actions[bot] commented 1 year ago

Merging because @dvlprsh is a code-owner of all the changes - thanks!