microsoft / TypeScript-Website-Localizations

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

Fix Typo in More on Functions.md #213

Open Seohyun-Roh opened 1 year ago

Seohyun-Roh commented 1 year ago

Destructing -> Destructuring

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 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 like other values, 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 _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 a parameter and has no return value". Like a function declaration, if the parameter is not typed, implicitly `any`will be. > If the parameter name is **essential** Keep in mind. Function Type `(string) => void`The "`any` With type `string`A function with a parameter named Of course, you can use type aliases to name types in functions. ```ts twoslash type GreetFunction = (a: string) => void; function greeter(fn: GreetFunction) { // ... } ``` ## Call Signature In JavaScript, functions can not only be called, but also have properties. However, the syntax of function type expressions does not allow you to define properties. If we try to describe something that is callable and has properties, the object type _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 parameter type and the type of the return value `=>`Not `:`must be used. ## Configuration Signatures JavaScript functions are `new`It can also be called through operators. TypeScript is mainly used to create new objects. _constructor_ Considered to be. You are in front of the call signature. `new` By attaching keywords, _Configuration Signatures_. ```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`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 common to write a function in a form where the input value is related to the type of the output value, or that the type of the two inputs is 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 `any` Is. It would be better if the function returned the type of the array element. In TypeScript, _Generic_ Grammars are used to express the correlation between two values. We select the function signature from _Type Parameters_You can make that expression by declaring. ```ts twoslash function firstElement(arr: Type[]): Type | undefined { return arr[0]; } ``` Type Parameters `Type`by declaring it to this function, and using it where we need it, we created a link between the function's input (array) and output (return value). 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 have `Type`Please note that it is not specified. where the type is _It has been deduced_ That is, it was automatically selected by TypeScript. We can also use multiple type parameters. For example, `map`The standalone version of will 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 is `Input` Type and (given as input `string` from array) `Output`Change the type to the return value of the function expression (`number`) to see what you can deduce. ### Type constraints We are _all_ We have written generic functions that operate on types. Sometimes, we want to relate two values, but only want them to work on a subset of certain values. In these cases, we have _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, the number is `length` Requires a property. `extends`Use the clause to change the type parameter to the 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 things to note. We have TypeScript `longest`The return type of _inference_ I allowed it to be. Return type inference also works with generic functions. We `Type`to `{ length: number }`Since we were limited to, we `a`and `b` About the parameters `.length` I was able to access the property. Without type restrictions, these values could be of other types that did not have a length property, so they would not have access to those properties. `longerArray`and `longerString`The type of was inferred based on the arguments. Remember that generics are when you associate two or more values 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 it didn't have the property. ### Working with restricted values The following are common mistakes to make 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 appears to have no problems. `Type`silver `{ lenght: number }`, and the function is `Type`or a value that satisfies that constraint. The problem is that this function satisfies the constraints _How_ Input, not an object _How_ The point is that it returns an object. If this 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 infers the intended type from generic calls, but this is not always the case. For example, suppose 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 unpaired array. ```ts twoslash // @errors: 2322 declare function combine(arr1: Type[], arr2: Type[]): Type[]; // ---cut--- const arr = combine([1, 2, 3], ["hello"]); ``` If you intended something like this, you can manually `Type`must be specified. ```ts twoslash declare function combine(arr1: Type[], arr2: Type[]): Type[]; // ---cut--- const arr = combine([1, 2, 3], ["hello"]); ``` ### Guidelines for writing good generic functions Writing generic functions can be fun, and using type parameters can be easy. Using too many type parameters or constraints where they aren't essential can make poor reasoning and frustrate your function callers. #### Pressing Type Parameters 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 inferred return type of this function is `Type` is, `firstElement2`The inferred return type of is more likely to be at the time of the call, rather than "waiting" for TypeScript to interpret the type during the call. `arr[0]` Because expressions are interpreted using type constraints. `any`will be. > **rule**: If possible, use the type parameter itself rather than constraining the type parameter. #### 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 _Do not associate two values_ Type Parameters `Func`has been created. This is not a good idea, because callers who want type arguments have to provide additional type arguments for no reason. `Func`only makes the function harder to read and understand, does nothing! > **rule**: Always use the minimum type parameter 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 to use it for the purpose of doing so. If a type parameter is used only once in a function signature, it is not associated with anything. > **rule**: If the type parameter only comes from one place, think again about whether you really need it. ## Optional Parameters Functions used in JavaScript often take a variable number of arguments. For example, `number`of `toFixed` The method optionally takes a number of digits. ```ts twoslash function f(n: number) { console.log(n.toFixed()); // 0 arguments console.log(n.toFixed(3)); // 1 argument } ``` In TypeScript, we can select the parameters `?`By marking with _Optional_Can be made with: ```ts twoslash function f(x?: number) { // ... } f(); // OK f(10); // OK ``` If the type of the parameter is `number`, but not specified in JavaScript, 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 it. ```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`will be. When the parameter is optional, the caller `undefined`, you can mimic 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 a callback: ```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?`When you write to use a XmlReader as an optional parameter, what you usually intend is to 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 one argument_ Is. In other words, the previous function definition is equivalent to 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 forces these semantics and throws an error 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 it is called by passing more arguments than specified as a 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 creating a function type for a callback, without the corresponding arguments _Call_ Unless there is an intention, _never_ Do not use optional parameters. ## Function overload Some JavaScript functions can be called with a variety of argument counts, types. For example, you can `Date`, take one timestamp (one argument), and take the month/day/year format (three arguments). In TypeScript, we have functions that can be called in different ways. _Overlord Signature_can be described by writing. To do this, you can write down a few function signatures (usually two or more) and then create 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, and the other receives three arguments. These two signatures were written at the beginning. _Overlord Signature_ It is called. Then, we wrote a function implementation with compatible signatures. The function is _Implement_ It has a signature, but it cannot be called directly. Although we have created two optional parameters after the essential 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 below, and sometimes they 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 create the function body is "invisible" from the outside. > _Implement_is not visible from the outside. > When you write an overloaded function, you _More than one_must be written above the function implementation. In addition, the implementation signature is an overloaded signature and _Must be compatible_ The. For example, the following functions have errors because their implementation signatures do 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 good overloads As with generics, there are some guidelines to follow when writing function overloads. Following these rules will make your functions easy to call, understand, and 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 via string or array. However, since TypeScript only interprets a function through a single overload, we can use this function as a string _or_ It cannot be called through a value that can be an array. ```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! Callers can call this function with either value, and additionally eliminate the need to find the exact implementation signature. > If possible, use union types instead of overloads ### Within a function `this` Declaring TypeScript is a function within `this`is inferred through code flow analysis as shown in the example below. ```ts twoslash const user = { id: 123, admin: false, becomeAdmin: function () { this.admin = true; }, }; ``` TypeScript is a function `user.becomeAdmin`This external object `user`Equivalent to `this`I understand that you have. Usually this may be enough, but you `this`You'll often need more control over what objects represent. The JavaScript specification states that `this`Because it says that you cannot have a parameter named , TypeScript uses that grammar space in the function body `this`Permits 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 that control when other objects call the function. To achieve this effect, you need to use the arrow function, not `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 you need to know When working with function types, there are a few more additional types that often appear. Like all types, you can use them anywhere, but they are particularly relevant to the context of functions. ### `void` `void`means the return value of a function that does not return a value. To the function `return`If 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, functions that return nothing implicitly `undefined` Returns a value. But in TypeScript `void`and `undefined`is not considered the same. We'll cover them in detail at the end of this chapter. > `void`The `undefined`is not the same as. ### `object` Special type `object`is the raw value (`string`, `number`, `bigint`, `boolean`, `symbol`, `null`, `undefined`) for any value. This is _Empty Object Type_ `{ }`, global type `Object`It's also different. 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, a function value is an object. It has properties, and in the prototype chain `Object.prototype`There is, `instanceof Object`In the meantime, `Object.keys`, etc. For this reason, in TypeScript, function types are `object`is considered. ### `unknown` `unknown` The type is _All Values_Indicates . `any` It is similar to a type, `unknown` It is safer to assign something to a type because it is not valid. ```ts twoslash // @errors: 2571 function f1(a: any) { a.b(); // OK } function f2(a: unknown) { a.b(); } ``` This means that `any` Since you can express a function that accepts any value without using the value of the type in the function body, it is useful for describing function types. Conversely, you can express 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` Some functions are _Never_ 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 the return type, it means that the function raises 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 Type `Function`silver `bind`, `call`, `apply` It is 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 such a call is `any`Returns. ```ts twoslash function doSomething(f: Function) { return f(1, 2, 3); } ``` This means that _Untyped function calls_ Unsafe, `any` It is generally best to avoid returning types. If you need to allow an arbitrary function, but don't intend to call it, `() => void` The type is generally safer. ## The rest of the parameters and arguments

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

### Rest Parameters We can use optional parameters and overloads to accept a variety of definite arguments, but we _Indeterminate_ A function that accepts arguments of a number _Remaining parameters_can be defined using The remaining parameters appear after all other parameters. `...` 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, type notation for these parameters is implicitly `any`Not `any[]`, and the type expression is `Array` or `T[]` Or it should be expressed as a tuple type (which we will learn later). ### Rest Argument On the contrary, we use the unfolding syntax to change the number of arguments supplied in the array to _offer_I can. For example, of `push` A method can accept 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 immutable. This can result in the following surprising behavior: ```ts twoslash // @errors: 2556 // 추론된 타입은 0개 이상의 숫자를 가지는 배열인 number[] // 명시적으로 2개의 숫자를 가지는 배열로 간주되지 않습니다 const args = [8, 5]; const angle = Math.atan2(...args); ``` The best solution for this situation depends on your 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 an older runtime, [`downlevelIteration`](/tsconfig#downlevelIteration)You may need to. ## Parameter Destructuring

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

You can use parameter decomposition to conveniently unpack the object supplied as an argument into one or more local variables in the function body. In JavaScript, it looks like the form below. ```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 placed after the decomposition statement. ```ts twoslash function sum({ a, b, c }: { a: number; b: number; c: number }) { console.log(a + b + c); } ``` It may seem a bit wordy, but you can use any 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); } ``` ## Assignmentability of functions ### `void` Return Type hydrous `void` Return types can cause some uncommon but predictable behavior. `void` Contextual typing into a return type 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 can be returned, but is ignored. Therefore, the type to be described later `() => void`are all 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 value of these functions is assigned to another variable, they still `void`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(); ``` Because this behavior exists, `Array.prototype.push`returns number, `Array.prototype.forEach` Method `void` Even if you expect a function with a return type, the following code might 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 should not return anything. **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 document items. - [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 93d4496f1b8abd3b89563ce2597c61305e3af164