Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove span tag in title and unnecessary TOC in Ko #164

Merged
merged 1 commit into from
Sep 15, 2022

Conversation

Jonghakseo
Copy link
Contributor

@ghost
Copy link

ghost commented Aug 14, 2022

CLA assistant check
All CLA requirements met.

@github-actions
Copy link
Contributor

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
Copy link
Contributor

Translation of TypeScript 3.9.md

title: TypeScript 3.9
layout: docs
permalink: /ko/docs/handbook/release-notes/typescript-3-9.html

oneline: TypeScript 3.9 Release Notes

Reasoning Promise.all Improvements in Inference and Promise.all)

The latest version of TypeScript (approx. 3.7) is Promise.all and Promise.raceUpdated function declarations such as .
Unfortunately, especially null or undefinedWhen mixing values with , a slight regression occurred.

interface Lion {
    roar(): void
}

interface Seal {
    singKissFromARose(): void
}

async function visitZoo(lionExhibit: Promise<Lion>, sealExhibit: Promise<Seal | undefined>) {
    let [lion, seal] = await Promise.all([lionExhibit, sealExhibit]);
    lion.roar(); // 오 이런
//  ~~~~
// 객체는 아마도 'undefined' 일 것입니다.
}

This behavior is strange!
sealExhibitprice undefinedIncluding the is somehow lion On Type undefinedInject the .

Jack Batesof pull request Thanks to this, the reasoning process in TypeScript 3.9 has been improved.
The above error no longer occurs.
PromiseIf you've struggled with previous versions of TypeScript because of issues related to , I recommend using 3.9.

awaited What is a type? (What About the awaited Type?)

If you've been looking at issue trackers and design meeting notes, awaited A new operator namedYou will be aware of some operations on .
The goal of this type operator is to use JavaScript Promiseis to model exactly how you solve it.

Initially, in TypeScript 3.9 awaited, but by running an initial TypeScript build with an existing code base, we found that this feature required more design work before it could be seamlessly deployed to all users.
As a result, we decided to remove this feature from the main branch until we became more certain.
We'll be experimenting more with this feature, but we won't be offering it in this release.

Speed Improvements

TypeScript 3.9 includes many new speed improvements.
Our team focused on performance after seeing that the edit/compilation speed was very poor when using packages like material-ui and styled-components.
We did an in-depth analysis with a variety of pull requests that optimize specific pathological cases involving huge unions, intersections, condition-specific types, and mapped types.

Each of these pull requests reduces compile time by approximately 5-10% on a particular code base.
In total, the compile time of material-ui has been reduced by about 40%!

In addition, the ability to change the file name in the editor scenario has been partially changed.
We were told by the Visual Studio Code team that it can take 5 to 10 seconds to figure out which import statement needs to be updated when renaming a file.
TypeScript 3.9 is Internal changes in the way compilers and language services cache file lookupsto resolve this issue.

There's still room for improvement, but we hope this will lead to a faster experience for everyone!

// @ts-expect-error Annotations (// @ts-expect-error Comments)

Write a library in TypeScript and as part of the public API doStuffImagine exporting a function named
Allowing TypeScript users to receive type-check errors doStuff The type of the function is two string, but also does a runtime error check to provide useful errors to JavaScript users (only during development builds).

function doStuff(abc: string, xyz: string) {
    assert(typeof abc === "string");
    assert(typeof xyz === "string");

    // 어떤 작업을 하세요
}

So TypeScript users will receive useful red error underscores and error messages if they use the function incorrectly, and JavaScript users will get assertion errors.
To test this behavior, I'm going to write a unit test.

expect(() => {
    doStuff(123, 456);
}).toThrow();

Unfortunately, if the above test is written in TypeScript, TypeScript will throw an error!

    doStuff(123, 456);
//          ~~~
// 오류: 'number' 타입은 'string' 타입에 할당할 수 없습니다.

That's why TypeScript 3.9 introduced new features: // @ts-expect-error Tin.
Before the line // @ts-expect-error If annotated, TypeScript stops reporting the error;
However, if the error does not exist, TypeScript // @ts-expect-errorwill report that it is not needed.

as a simple example the following code is fine

// @ts-expect-error
console.log(47 * "octopus");

However, the following code

// @ts-expect-error
console.log(1 + 1);

will lead to an error

Unused '@ts-expect-error' directive.

Contributors who have implemented this feature, Josh GoldbergA big thank you.
For more information, see the ts-expect-error pull requestSee .

ts-ignore or ts-expect-error? (ts-ignore or ts-expect-error?)

In a way, // @ts-expect-errorprice // @ts-ignoreSimilar to , it can act as a suppression comment.
The difference is // @ts-ignoremeans that if there is no error on the next line, do nothing.

Existing // @ts-ignore Comments // @ts-expect-error, and you may be wondering what would be a good fit for your future code.
It's entirely up to you and your team, but we have some ideas on which one to choose in which situation.

If the following are the cases: ts-expect-errorSelect :

  • If you want to write test code where the type system causes an error in its operation
  • If you want a fix to happen quickly and you need a quick solution
  • If you are working on a moderate-sized project led by an innovative team that wants to delete suppression comments as soon as the code that has encountered the error becomes valid again.

If the following are the cases: ts-ignoreSelect :

  • If you have a larger project and have a hard time finding a clear responsible person for new errors in your code.
  • You are upgrading between two versions of TypeScript, and you are getting a code error in one version but not in the other.
  • If you honestly don't have time to decide which option is better.

Uncalled Function Checks in Conditional Expressions

To report an error if TypeScript 3.7 forgets to call a function _Check an uncalled function_Introduced.

function hasImportantPermissions(): boolean {
    // ...
}

// 이런!
if (hasImportantPermissions) {
//  ~~~~~~~~~~~~~~~~~~~~~~~
// hasImportantPermissions 함수가 항상 정의되어 있기 때문에, 이 조건문은 항상 true를 반환합니다.
// 대신 이것을 호출하려 하셨나요?
    deleteAllTheImportantFiles();
}

However, this error is if Applies only to the terms of the inquiry.
Alexander Tarasyukof a pull request Thanks to this, this feature also supports ternary conditional operators (e.g. cond ? trueExpr : falseExpr syntax).

declare function listFilesOfDirectory(dirPath: string): string[];
declare function isDirectory(): boolean;

function getAllFiles(startFileName: string) {
    const result: string[] = [];
    traverse(startFileName);
    return result;

    function traverse(currentPath: string) {
        return isDirectory ?
        //     ~~~~~~~~~~~
        // isDirectory 함수가 항상 정의되어 있기 때문에,
        // 이 조건문은 항상 true를 반환합니다
        // 대신 이것을 호출하려 하셨나요?
            listFilesOfDirectory(currentPath).forEach(traverse) :
            result.push(currentPath);
    }
}

microsoft/TypeScript#36048

Editor Improvements

The TypeScript compiler affects not only the TypeScript writing experience of the major editors, but also the JavaScript writing experience of the Visual Studio family of editors.
Using the new TypeScript/JavaScript features in the editor will vary depending on the editor.

CommonJS Auto-Import in JavaScript

The auto-import functionality for JavaScript files that use the CommonJS module has been greatly improved.

In previous versions, TypeScript always assumed that you wanted an ECMAScript-style import, regardless of the file.

import * as fs from "fs";

However, not everyone wants an ECMAScript-style module when writing JavaScript files.
Many users are still in CommonJS-style require(...) I'm using import.

const fs = require("fs");

TypeScript now automatically detects the type of import you are using to keep the file style clean and consistent.

For more information about this change, see The pull requestSee .

Code Actions Preserve Newlines

TypeScript's refactoring and quick fixes often didn't do much to keep newlines.
As a basic example, consider the following code:

const maxValue = 100;

/*시작*/
for (let i = 0; i <= maxValue; i++) {
    // 먼저 제곱 값을 구한다.
    let square = i ** 2;

    // 제곱 값을 출력한다.
    console.log(square);
}
/*끝*/

In the Editor /*시작*/ In /*끝*/ If you highlight the range up to and extract it into a new function, you will get the following code:

const maxValue = 100;

printSquares();

function printSquares() {
    for (let i = 0; i <= maxValue; i++) {
        // 먼저 제곱 값을 구한다.
        let square = i ** 2;
        // 제곱 값을 출력한다.
        console.log(square);
    }
}

이전 버전의 TypeScript에선 함수로 루프 추출은. 개행을 유지하지 않습니다.

This is not ideal - for There was a blank line between each door in the loop, but the refactoring got rid of it!
TypeScript 3.9 does a little more to preserve what we write.

const maxValue = 100;

printSquares();

function printSquares() {
    for (let i = 0; i <= maxValue; i++) {
        // 먼저 제곱 값을 구한다.
        let square = i ** 2;

        // 제곱값을 출력한다.
        console.log(square);
    }
}

TypeScript 3.9의 함수에 대한 루프 추출. 개행이 보존됨

this pull requestYou can read more about the implementation in .

Quick Fixes for Missing Return Expressions

Especially when you add braces to an arrow function, you may forget to return the value of the last statement in the function.

// 이전
let f1 = () => 42

// 실수 - 동일하지 않음!
let f2 = () => { 42 }

Community Members Wenlu Wangof pull request Thanks to this, TypeScript is missing return You can provide a quick-fix to add statements, remove braces, or add parentheses to the arrow function body that looks like an object literal.

TypeScript는 `return` 문을 추가하거나 중괄호를 제거하여 식이 반환되지 않는 오류를 수정합니다.

tsconfig.json Support for "Solution Style" tsconfig.json Files)

The editor needs to figure out which configuration files belong so that the appropriate options can be applied, and what other files are currently included in the "project".
By default, the editor that TypeScript's language server affects goes up along each parent directory. tsconfig.jsonDo this by finding .

One of the occasions when this problem somewhat failed was when tsconfig.json simply existed to reference another tsconfig.json file.

// tsconfig.json
{
    "files": [],
    "references": [
        { "path": "./tsconfig.shared.json" },
        { "path": "./tsconfig.frontend.json" },
        { "path": "./tsconfig.backend.json" },
    ]
}

This file, which only manages other project files, is often referred to as a "solution" in some environments.
Here tsconfig.*.json None of the files are detected by the server, but are currently .ts The file is in the root of the tsconfig.jsonI want the language server to understand that it belongs to one of the projects mentioned in .

TypeScript 3.9 supports scenario modifications to this setting.
For more details, A pull request that added this featureCheck it out.

Breaking Changes

Parsing Differences in Optional Chaining and Non-Null Assertions

Recently, TypeScript introduced an optional chaining operator, but it is not a null assertive operator (!Optional chaining ( ) used with?.) has received user feedback that its behavior is not very intuitive.

Specifically, in earlier versions, the code was

foo?.bar!.baz

It was interpreted the same as the following JavaScript:

(foo?.bar).baz

In the code above, the parentheses will stop the "short" behavior of the optional chaining, so if fooprice undefinedBehind the scenes, bazAccessing will result in a runtime error.

The Babel team that pointed out this behavior and most of the users who gave feedback believe it is incorrect.
We think so!
barIn the type of nulland undefinedThe most heard word is that it is the intention to get rid of the ! The operator is just "should disappear".

In other words, most people believe that the original sentence is as follows:

foo?.bar.baz

fooprice undefinedWhen it does, just undefinedI think it should be interpreted as evaluating as

While this is a major change, I think most of the code was written with the new interpretation in mind.
Users who want to revert to the previous behavior ! You can add explicit parentheses to the left of the operator.

(foo?.bar)!.baz

} and > is now an invalid JSX text character (} and > are Now Invalid JSX Text Characters)

JSX statements have a text location in }and > The use of characters is prohibited.
TypeScript and Babel decided to apply this rule more appropriately.
A new way to put this character is by using HTML escape code (for example, <span> 2 &gt 1 </div>) is to put the expression as a string literal (e.g. <span> 2 {">"} 1 </div).

fortunately Brad Zacherof pull request thanks to this you may receive an error message with the following sentence

Unexpected token. Did you mean `{'>'}` or `&gt;`?
Unexpected token. Did you mean `{'}'}` or `&rbrace;`?

For example:

let directions = <span>Navigate to: Menu Bar > Tools > Options</div>
//                                           ~       ~
// Unexpected token. Did you mean `{'>'}` or `&gt;`?

This error message comes with a convenient and quick fix Alexander Tarasyuk Thanks, if there are many errors You can apply these changes in batches.

Stricter Checks on Intersections and Optional Properties

generally A & BIntersection types such as A or Bprice CIf it can be assigned to , A & BThe Ccan be assigned to; However, sometimes there is a problem with optional properties.
For example, let's see:

interface A {
    a: number; // 'number' 인 것에 주목
}

interface B {
    b: string;
}

interface C {
    a?: boolean; // 'boolean' 인것에 주목
    b: string;
}

declare let x: A & B;
declare let y: C;

y = x;

In previous versions of TypeScript: Aprice CAlthough not fully compatible with, Bprice CCompatible with Was Because it was allowed.

In TypeScript 3.9, if all types in an intersection are salvific object types, the type system considers all properties at once.
As a result, TypeScript is A & Bof a Properties are Cof a I don't think it's compatible with the property:

'A & B' 타입은 'C' 타입에 할당할 수 없습니다.
  'a' 프로퍼티의 타입은 호환되지 않습니다.
    'number' 타입은 'boolean | undefined' 타입에 할당할 수 없습니다.

For more information about these changes, see The pull requestSee .

Intersections Reduced By Discriminant Properties

There are a few cases in which you might end up with a type that describes a value that doesn't exist.
For example

declare function smushObjects<T, U>(x: T, y: U): T & U;

interface Circle {
    kind: "circle";
    radius: number;
}

interface Square {
    kind: "square";
    sideLength: number;
}

declare let x: Circle;
declare let y: Square;

let z = smushObjects(x, y);
console.log(z.kind);

This code is Circleand SquareIt's a bit odd because there is no way to create an intersection of - two incompatible kind There is a field.
In previous versions of TypeScript, this code was allowed. "circle" & "square"price 절대(never) Because you described a set of values that cannot exist kind The type of itself is neverWas.

In TypeScript 3.9, the type system is more aggressive − kind Because of the properties Circleand SquareI know it's impossible to cross .
so z.kind neverInstead of collapsing to , z The self (Circle & Squarea) type neverCollapse to .
In other words, the above code throws the following error:

'kind' 프로퍼티는 'never' 타입에 존재하지 않습니다.

Most of the errors I've observed seem to match an invalid type declaration.
For more information, see Original pull requestTake a look.

Getters/Setters are No Longer Enumerable

In previous versions of TypeScript, the class getand set The accessors were released in an enumerable way; but getand setdid not follow the ECMAScript specification that it cannot be enumerated.
As a result, TypeScript code that targets ES5 and ES2015 may have different behaviors.

GitHub users pathursof pull request Thanks to this, TypeScript 3.9 is more closely compatible with ECMAScript in this regard.

anyType parameters extended to no longer any Type Parameters That Extend any No Longer Act as any)

In previous versions of TypeScript anyType parameters limited to anyWe were able to deal with it.

function foo<T extends any>(arg: T) {
    arg.spfjgerijghoied; // 오류가 아님!
}

This was a mistake, so TypeScript 3.9 takes a more conservative approach and throws errors for these suspicious operations.

function foo<T extends any>(arg: T) {
    arg.spfjgerijghoied;
    //  ~~~~~~~~~~~~~~~
    // 'spfjgerijghoied' 프로퍼티는 'T' 타입에 존재하지 않습니다.
}

export *is always maintained (export * is Always Retained)

In previous versions of TypeScript export * from "foo" The same declaration is fooIf does not export any value, it is excluded from the JavaScript output.
This kind of export is problematic because it is type-oriented and cannot be emulated in barbell.
TypeScrip 3.9 is like this export * Declarations are always exported.
In fact, I don't think this change will break existing code.

More libdom.d.ts refinements

TypeScript's built-in .d.ts right from the Web IDL file. Built-in .d.ts of DOM-compliant TypeScript so that libraries (lib.d.ts and families) can be generated. I'm still working on moving the library.
As a result, some vendor-specific types related to media access have been removed.

If you add this file to your project's ambient *.d.ts file, you can recover it back:

interface HTMLVideoElement {
  msFrameStep(forward: boolean): void;
  msInsertVideoEffect(activatableClassId: string, effectRequired: boolean, config?: any): void;
  msSetVideoRectangle(left: number, top: number, right: number, bottom: number): void;
  webkitEnterFullScreen(): void;
  webkitEnterFullscreen(): void;
  webkitExitFullScreen(): void;
  webkitExitFullscreen(): void;

  msHorizontalMirror: boolean;
  readonly msIsLayoutOptimalForPlayback: boolean;
  readonly msIsStereo3D: boolean;
  msStereo3DPackingMode: string;
  msStereo3DRenderMode: string;
  msZoom: boolean;
  onMSVideoFormatChanged: ((this: HTMLVideoElement, ev: Event) => any) | null;
  onMSVideoFrameStepCompleted: ((this: HTMLVideoElement, ev: Event) => any) | null;
  onMSVideoOptimalLayoutChanged: ((this: HTMLVideoElement, ev: Event) => any) | null;
  webkitDisplayingFullscreen: boolean;
  webkitSupportsFullscreen: boolean;
}

interface MediaError {
  readonly msExtendedCode: number;
  readonly MS_MEDIA_ERR_ENCRYPTED: number;
}
Translation of TypeScript 3.8.md

title: TypeScript 3.8
layout: docs
permalink: /ko/docs/handbook/release-notes/typescript-3-8.html

oneline: TypeScript 3.8 Release Notes

Type-Only Imports and Exports

Although this feature may not be a no-brainer for most users; --isolatedModules, TypeScript transpileModule If you encounter a problem with the API, or Babel, it may be related to this feature.

TypeScript 3.8 adds a new syntax for type-only imports, exports.

import type { SomeThing } from "./some-module.js";

export type { SomeThing };

import typeimports only declarations that will be used for type notation and declarations.
This means that All the time It is completely removed, so there is nothing left at runtime.
likewise export typeprovides only exports for use in the type context, which is also removed from the TypeScript's output.

It's important to note that classes have values at runtime, have types at design-time, and their use is contextual-dependent.
To import a class import typeWith , you can't do anything like extensions.

import type { Component } from "react";

interface ButtonProps {
    // ...
}

class Button extends Component<ButtonProps> {
    //               ~~~~~~~~~
    // error! 'Component' only refers to a type, but is being used as a value here.

    // ...
}

If you've used Flow before, the syntax is quite similar.
One difference is that I put some restrictions in place to make the code look vague.

// 'Foo'만 타입인가? 혹은 모든 import 선언이 타입인가?
// 이는 명확하지 않기 때문에 오류로 처리합니다.

import type Foo, { Bar, Baz } from "some-module";
//     ~~~~~~~~~~~~~~~~~~~~~~
// error! A type-only import can specify a default import or named bindings, but not both.

import typeAlong with , TypeScript 3.8 adds a new compiler flag to control what happens with an unused import at run time: importsNotUsedAsValues.
This flag has 3 different values:

  • remove: This is the current behavior of removing imports, and will continue to work as the default, not a change that replaces the existing behavior.
  • preserve: This means that all unused values are _conservation_The. This can preserve imports/side-effects.
  • error: This means that all (preserve option) preserves all imports, but throws an error if the import value is used only as a type. This is useful when you don't accidentally import the value, but you want to explicitly create a side effect import.

For more information about this feature, import typeExpanding the scope for which declarations can be used pull requestand Related changesYou can find it here.

ECMAScript Private Fields

TypeScript 3.8 is the name of ECMAScript stage-3 class field proposalSupports private fields in .

class Person {
    #name: string

    constructor(name: string) {
        this.#name = name;
    }

    greet() {
        console.log(`Hello, my name is ${this.#name}!`);
    }
}

let jeremy = new Person("Jeremy Bearimy");

jeremy.#name
//     ~~~~~
// 프로퍼티 '#name'은 'Person' 클래스 외부에서 접근할 수 없습니다.
// 이는 비공개 식별자를 가지기 때문입니다.

Common properties (private Unlike anything you declare as a specifier), private fields have a few rules to keep in mind.
Some of them are:

  • The private field is # Starts with a letter. Sometimes it is possible to do this Private names Called.
  • All private field names are unique in the class scope that contains them.
  • public or private The same TypeScript access specifier cannot be used as a private field.
  • Even from JS users, private fields cannot be accessed or detected outside of the class that contains them! Sometimes it is possible to do this Hard privacy Call.

Apart from the "strong" private, another advantage of a private field is that it is unique.
For example, a typical property declaration is easy to overwrite in a subclass.

class C {
    foo = 10;

    cHelper() {
        return this.foo;
    }
}

class D extends C {
    foo = 20;

    dHelper() {
        return this.foo;
    }
}

let instance = new D();
// 'this.foo' 는 각 인스턴스마다 같은 프로퍼티를 참조합니다.
console.log(instance.cHelper()); // '20' 출력
console.log(instance.dHelper()); // '20' 출력

In private fields, you don't have to worry about this because each field name is unique in the class you contain.

class C {
    #foo = 10;

    cHelper() {
        return this.#foo;
    }
}

class D extends C {
    #foo = 20;

    dHelper() {
        return this.#foo;
    }
}

let instance = new D();
// 'this.#foo' 는 각 클래스안의 다른 필드를 참조합니다.
console.log(instance.cHelper()); // '10' 출력
console.log(instance.dHelper()); // '20' 출력

Another thing that is good to know is that if you approach a private field with a different type, TypeError is that it happens.

class Square {
    #sideLength: number;

    constructor(sideLength: number) {
        this.#sideLength = sideLength;
    }

    equals(other: any) {
        return this.#sideLength === other.#sideLength;
    }
}

const a = new Square(100);
const b = { sideLength: 100 };

// Boom!
// TypeError: attempted to get private field on non-instance
// 이는 `b` 가 `Square`의 인스턴스가 아니기 때문에 실패 합니다.
console.log(a.equals(b));

As a subtitle, all plain .js For file users, the private field is All the time It must be declared before it can be assigned.

class C {
    // '#foo' 선언이 없습니다.
    // :(

    constructor(foo: number) {
        // SyntaxError!
        // '#foo'는 쓰여지기 전에 선언되어야 합니다.
        this.#foo = foo;
    }
}

JavaScript has always allowed users access to undeclared properties, but TypeScript has always required class property declarations.
The private field is, .js or .ts You always need a declaration, regardless of whether it works on the file.

class C {
    /** @type {number} */
    #foo;

    constructor(foo: number) {
        // 동작합니다.
        this.#foo = foo;
    }
}

For more information about the implementation, the original pull requestSee

Which one should I use? (Which should I use?)

As a TypeScript user, I've already been asked a lot of questions about what kind of private I should use: mainly, "private Should I use keywords or hashes/wells in ECMAScript (#) Should I use a private field?"
Every situation varies!

In the property, the TypeScript private The specifier is completely cleared - it behaves like a completely normal property at runtime, and this is why private There is no way to say that it has been declared as a specifier.
private When using keywords, non-disclosure is enforced only at compile-time/design-time, and is entirely intention-based for JavaScript users.

class C {
    private foo = 10;
}

// 이는 컴파일 타임에 오류이지만
// TypeScript 가 .js 파일로 출력했을 때는
// 잘 동작하며 '10'을 출력합니다.
console.log(new C().foo);    // '10' 출력
//                  ~~~
// error! Property 'foo' is private and only accessible within class 'C'.

// TypeScript 오류를 피하기 위한 "해결 방법" 으로
// 캄파일 타임에 이것을 허용합니다.
console.log(new C()["foo"]); // prints '10'

This kind of "soft privacy" helps users work temporarily without access to the API, and it works at any runtime.

On the other hand, ECMAScript's # Private is completely inaccessible outside of class.

class C {
    #foo = 10;
}

console.log(new C().#foo); // SyntaxError
//                  ~~~~
// TypeScript 는 오류를 보고 하며 *또한*
// 런타임에도 동작하지 않습니다.

console.log(new C()["#foo"]); // undefined 출력
//          ~~~~~~~~~~~~~~~
// TypeScript 는 'noImplicitAny' 하에서 오류를 보고하며
// `undefined`를 출력합니다.

This kind of hard privacy is useful for strictly ensuring that no one can use the interior.
If you are a library author, removing or renaming private fields should not result in drastic changes.

As mentioned, the other advantages of ECMAScript # Private Price real It's just that it's private, so you can easily do subclassing.
ECMAScript # With private fields, no subclass has to worry about fieldnaming conflicts.
TypeScript privateIn a property declaration, the user must still be careful not to trample on the property declared in the parent class.

One more thing to think about is where you intend your code to run.
Currently, TypeScript cannot support this feature unless it targets ECMAScript 2015 (ES6) or a later version.
This means that low-level implementations are forced to be private. WeakMapto use, WeakMapThis is because it cannot be polyfilled to avoid losing memory leaks.
On the other hand, TypeScript's private- Declarative properties work on all targets - even in ECMAScript3!

The last consideration may be speed: private Because a property is no different from any other property, it can target any runtime and be as fast as any other property at the bottom.
On the other hand # The private field is WeakMapBecause you are downleveling with , it may slow down your usage.
What runtime is # Optimize private field implementation, faster WeakMapYou may want to implement , but this may not be the case at all runtimes.

export * as ns Syntax (export * as ns Syntax)

It is often common to have a single entry point that exports all members of different modules as one member.

import * as utilities from "./utilities.js";
export { utilities };

This is so common that ECMAScript2020 recently added a new syntax to support this pattern.

export * as utilities from "./utilities.js";

This is a great quality of life improvement for JavaScript, and TypeScript 3.8 supports this syntax.
Module target es2020 If it was the former, TypeScript would print something along the snippet of code on the first line.

Top-Level await (Top-Level await)

TypeScript 3.8 states that "top-level" awaitSupports a handy ECMAScript function called "ECMAScript".

JavaScript users awaitTo use the async You often introduce a function, and after you define it, you call the function immediately.

async function main() {
    const response = await fetch("...");
    const greeting = await response.text();
    console.log(greeting);
}

main()
    .catch(e => console.error(e))

In previous JavaScript (along with most other languages with similar functionality) awaitsilver async Because it was only allowed within the function.
But top-level awaitBy, we are at the top level of the module awaitYou can use .

const response = await fetch("...");
const greeting = await response.text();
console.log(greeting);

// 모듈인지 확인
export {};

Here's a point to keep in mind: Top-Level awaitsilver _module_Only works at the top level of , and the file is not TypeScript importI exportis considered a module only when it is found.
In some basic cases export {}It is necessary to verify this by creating a boilerplate such as .

In all environments where this is expected, the top level awaitmay not work.
present target Compiler options es2017 It is ideal, moduleTwo esnext or systemOnly the top level is awaitYou can use .
Support in some environments and bundlers may work with limitations or you may need to enable experimental support.

For more information on implementation, see Check the original pull request.

es2020dragon targetand module (es2020 for target and module)

TypeScript 3.8 is es2020 moduleand target Support as an option.
This allows for optional chaining, nullish coalescing, export * as ns and dynamic import(...) ECMAScript 2020 functionality, such as syntax, is preserved.
In addition bigint Literal esnext Stable under targetIt means having a .

JSDoc Property Modifiers

TypeScript 3.8 is allowJs Supports JavaScript files with flags checkJs Options or // @ts-check Comments .js Add to the top of the file to the JavaScript file _Type-Inspection_Supported.

Because JavaScript files do not have a dedicated syntax for type-checking, TypeScript leverages JSDoc.
TypeScript 3.8 recognizes several new JSDoc tags for properties.

First is the access specifier: @public, @private and @protectedIs.
Each of these tags is within TypeScript. public, private, protectedWorks the same as .

// @ts-check

class Foo {
    constructor() {
        /** @private */
        this.stuff = 100;
    }

    printStuff() {
        console.log(this.stuff);
    }
}

new Foo().stuff;
//        ~~~~~
// 오류! 'stuff' 프로퍼티는 private 이기 때문에 오직 'Foo' 클래스 내에서만 접근이 가능합니다.
  • @publicis always implicit and can be omitted, but it means that the property is accessible from anywhere.
  • @privatemeans that the property is available only within the class containing the property.
  • @protectedcan use that property within the class containing the property and any derived subclasses, but instances of the containing class cannot use that property.

Next: @readonly Add a specifier to ensure that the property is only used within the initialization process.

// @ts-check

class Foo {
    constructor() {
        /** @readonly */
        this.stuff = 100;
    }

    writeToStuff() {
        this.stuff = 200;
        //   ~~~~~
        // 'stuff'는 읽기-전용(read-only) 프로퍼티이기 때문에 할당할 수 없습니다.
    }
}

new Foo().stuff++;
//        ~~~~~
// 'stuff'는 읽기-전용(read-only) 프로퍼티이기 때문에 할당할 수 없습니다.

Better directory monitoring in Linux watchOptions

In TypeScript 3.8, node_modulesprovides a new directory witness strategy that is important for efficiently collecting changes.

In an operating system such as Linux, TypeScript is node_modulesInstall directory watchers (as opposed to file watchers) on , and many subdirectories to detect dependency changes.
Because the number of available file watchers is often node_modulesis obscured by the number of files in , and because the number of directories to track is small.

Earlier versions of TypeScript put watchers in a folder in the directory promptly Install it, and it should be fine initially; But, when you install npm, node_modulesA lot of things will happen inside, and it will overwhelm TypeScript, often making the editor session very slow.
To prevent this, TypeScript 3.8 waits a bit before installing directory watcher to give highly volatile directories time to be stable.

Because every project may work better with a different strategy, and this new approach may not work well in your workflow. TypeScript 3.8 allows you to tell the compiler/language service what watchdog strategy to use to monitor files and directories. tsconfig.jsonand jsconfig.jsonat watchOptionsprovides a new field.

{
    // 일반적인 컴파일러 옵션들
    "compilerOptions": {
        "target": "es2020",
        "moduleResolution": "node",
        // ...
    },

    // NEW: 파일/디렉터리 감시를 위한 옵션
    "watchOptions": {
        // 파일과 디렉터리에 네이티브 파일 시스템 이벤트 사용
        "watchFile": "useFsEvents",
        "watchDirectory": "useFsEvents",

        // 업데이트가 빈번할 때
        // 업데이트하기 위해 더 자주 파일을 폴링
        "fallbackPolling": "dynamicPriority"
    }
}

watchOptionsincludes 4 new options that you can configure.

  • watchFile: Strategy of how to watch each file. You can set it up as follows:
    • fixedPollingInterval: Checks for changes to all files several times in 1 second at fixed intervals.
    • priorityPollingInterval: Changes to all files are scanned several times in 1 second, but heuristics are used to scan files of one type less frequently than other types of files.
    • dynamicPriorityPolling: Uses dynamic queues to check fewer files that are modified less frequently.
    • useFsEvents (default): Uses OS/file system native events for file changes.
    • useFsEventsOnParentDirectory: When detecting a change to a directory containing a file, it uses the native events of the operating system/file system. You can use less file watcher, but it may be less accurate.
  • watchDirectory: A strategy in which the entire directory tree is watched within a system that does not have recursive file-watching. You can set it up as follows:
    • fixedPollingInterval: Checks for changes to all directories at fixed intervals several times in 1 second.
    • dynamicPriorityPolling: Use dynamic queues to examine less frequently modified directories.
    • useFsEvents (default): Uses OS/file system native events for directory changes.
  • fallbackPolling: When using file system events, this option specifies the polling strategy used when the system lacks native file watcher and/or does not support it. You can set it up like this:
    • fixedPollingInterval: (See above.)
    • priorityPollingInterval: (See above.)
    • dynamicPriorityPolling: (See above.)
  • synchronousWatchDirectory: Disables deferred supervision of directories. Deferred watch is useful when many files are changed at once (for example, npm installRun the node_modulesof changes), but can also be disabled for less-general settings.

For more information about this change, go to Github the pull requestRead on.

"Fast and loose" incremental checking

TypeScript 3.8 has new compiler options assumeChangesOnlyAffectDirectDepenciesto provide.
When this option is enabled, TypeScript does not rescan/rebuild files that are really affected, but only rescans/rebuilds files that have been imported directly, as well as changed files.

For example, as follows: fileA.tsImport a fileB.tsImport a fileC.tsImport a fileD.tsLet's take a look at:

fileA.ts <- fileB.ts <- fileC.ts <- fileD.ts

--watch In mode, fileA.tsThe change of fileB.ts, fileC.ts and fileD.tsThis means that TypeScript must be re-checked.
assumeChangesOnlyAffectDirectDependenciesIn fileA.tsThe change of fileA.tsand fileB.tsYou only need to re-check.

In a code base like Visual Studio Code, we've reduced the rebuild time from about 14 seconds to about 1 second for changes to certain files.
This option is not recommended for all code bases, but if you have a large code base and are willing to defer the entire project error until later (for example, tsconfig.fullbuild.jsonor a dedicated build via CI) would be interesting.

For more information, see the original pull requestYou can see it here.

Generated by 🚫 dangerJS against f8c7b71

@Jonghakseo Jonghakseo changed the title Remove span tag in title and unnecessary TOC Remove span tag in title and unnecessary TOC in Ko Aug 14, 2022
@Jonghakseo
Copy link
Contributor Author

@bumkeyy @yeonjuan 리뷰 부탁드립니다~!

@bumkeyy
Copy link
Contributor

bumkeyy commented Sep 15, 2022

LGTM

@github-actions github-actions bot merged commit f50d485 into microsoft:main Sep 15, 2022
@github-actions
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants