| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
Thanks for the PR! This section of the codebase is owned by Kibeom Kwon (@bumkeyy), YeonJuan (@yeonjuan), Dan Jeong (@guyeol), and Seohee Park (@dvlprsh) - if they write a comment saying "LGTM" then it will be merged. |
Sorry, something went wrong.
|
Translation of TypeScript 3.9.md
title: TypeScript 3.9 oneline: TypeScript 3.9 Release NotesReasoning 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 . 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! Jack Batesof pull request Thanks to this, the reasoning process in TypeScript 3.9 has been improved. 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 . 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. Speed ImprovementsTypeScript 3.9 includes many new speed improvements.
Each of these pull requests reduces compile time by approximately 5-10% on a particular code base. In addition, the ability to change the file name in the editor scenario has been partially changed. 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 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. 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. 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. 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. Existing // @ts-ignore Comments // @ts-expect-error, and you may be wondering what would be a good fit for your future code. If the following are the cases: ts-expect-errorSelect :
If the following are the cases: ts-ignoreSelect :
Uncalled Function Checks in Conditional ExpressionsTo 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. 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);
}
}Editor ImprovementsThe 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.
CommonJS Auto-Import in JavaScriptThe 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. 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 NewlinesTypeScript's refactoring and quick fixes often didn't do much to keep newlines. 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);
}
}This is not ideal - for There was a blank line between each door in the loop, but the refactoring got rid of it! const maxValue = 100;
printSquares();
function printSquares() {
for (let i = 0; i <= maxValue; i++) {
// 먼저 제곱 값을 구한다.
let square = i ** 2;
// 제곱값을 출력한다.
console.log(square);
}
}this pull requestYou can read more about the implementation in . Quick Fixes for Missing Return ExpressionsEspecially 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. 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". 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. TypeScript 3.9 supports scenario modifications to this setting. Breaking ChangesParsing Differences in Optional Chaining and Non-Null AssertionsRecently, 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!.bazIt was interpreted the same as the following JavaScript: (foo?.bar).bazIn 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. In other words, most people believe that the original sentence is as follows: foo?.bar.bazfooprice 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. (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. fortunately Brad Zacherof pull request thanks to this you may receive an error message with the following sentence Unexpected token. Did you mean `{'>'}` or `>`?
Unexpected token. Did you mean `{'}'}` or `}`?
For example: let directions = <span>Navigate to: Menu Bar > Tools > Options</div>
// ~ ~
// Unexpected token. Did you mean `{'>'}` or `>`?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 Propertiesgenerally 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. 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. 'A & B' 타입은 'C' 타입에 할당할 수 없습니다.
'a' 프로퍼티의 타입은 호환되지 않습니다.
'number' 타입은 'boolean | undefined' 타입에 할당할 수 없습니다.
For more information about these changes, see The pull requestSee . Intersections Reduced By Discriminant PropertiesThere are a few cases in which you might end up with a type that describes a value that doesn't exist. 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 TypeScript 3.9, the type system is more aggressive − kind Because of the properties Circleand SquareI know it's impossible to cross . 'kind' 프로퍼티는 'never' 타입에 존재하지 않습니다. Most of the errors I've observed seem to match an invalid type declaration. Getters/Setters are No Longer EnumerableIn 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. 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. More libdom.d.ts refinementsTypeScript'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. 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;
}title: TypeScript 3.8 oneline: TypeScript 3.8 Release NotesType-Only Imports and ExportsAlthough 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. It's important to note that classes have values at runtime, have types at design-time, and their use is contextual-dependent. 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. // '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.
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 FieldsTypeScript 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.
Apart from the "strong" private, another advantage of a private field is that it is unique. 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. 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?" 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. 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. As mentioned, the other advantages of ECMAScript # Private Price real It's just that it's private, so you can easily do subclassing. One more thing to think about is where you intend your code to run. 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. 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. 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. 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 all environments where this is expected, the top level awaitmay not work. 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. JSDoc Property ModifiersTypeScript 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. First is the access specifier: @public, @private and @protectedIs. // @ts-check
class Foo {
constructor() {
/** @private */
this.stuff = 100;
}
printStuff() {
console.log(this.stuff);
}
}
new Foo().stuff;
// ~~~~~
// 오류! 'stuff' 프로퍼티는 private 이기 때문에 오직 'Foo' 클래스 내에서만 접근이 가능합니다.
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 watchOptionsIn 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. 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. 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.
For more information about this change, go to Github the pull requestRead on. "Fast and loose" incremental checkingTypeScript 3.8 has new compiler options assumeChangesOnlyAffectDirectDepenciesto provide. 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. 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. For more information, see the original pull requestYou can see it here. |
Sorry, something went wrong.
|
Kibeom Kwon (@bumkeyy) YeonJuan (@yeonjuan) 리뷰 부탁드립니다~! |
Sorry, something went wrong.
|
LGTM |
Sorry, something went wrong.
|
Merging because Kibeom Kwon (@bumkeyy) is a code-owner of all the changes - thanks! |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
In the Korean release notes document, toc malfunctions due to unnecessary span tags.