- ํ์ -์ ์ฉ Imports ์ Exports
- ECMAScript ๋น๊ณต๊ฐ ํ๋
export * as ns
๊ตฌ๋ฌธ- ์ต์์-๋ ๋ฒจ
await
- JSDoc ํ๋กํผํฐ ์ง์ ์
- ๋ฆฌ๋
์ค์์ ๋ ๋์ ๋๋ ํฐ๋ฆฌ ๊ฐ์์
watchOptions
- "๋น ๋ฅด๊ณ ๋์จํ" ์ฆ๋ถ ๊ฒ์ฌ
์ด ๊ธฐ๋ฅ์ ๋๋ถ๋ถ์ ์ฌ์ฉ์์๊ฒ ์๊ฐํ ํ์๊ฐ ์์ ์๋ ์์ง๋ง; --isolatedModules
, TypeScript์ transpileModule
API, ๋๋ Babel์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฉด ์ด ๊ธฐ๋ฅ๊ณผ ๊ด๋ จ์ด ์์ ์ ์์ต๋๋ค.
TypeScript 3.8์ ํ์ -์ ์ฉ imports, exports๋ฅผ ์ํ ์๋ก์ด ๊ตฌ๋ฌธ์ด ์ถ๊ฐ๋์์ต๋๋ค.
import type { SomeThing } from "./some-module.js";
export type { SomeThing };
import type
์ ํ์
ํ๊ธฐ์ ์ ์ธ์ ์ฌ์ฉ๋ ์ ์ธ๋ง import ํฉ๋๋ค.
์ด๋ ํญ์ ์์ ํ ์ ๊ฑฐ๋๋ฏ๋ก, ๋ฐํ์์ ๋จ์์๋ ๊ฒ์ ์์ต๋๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก, export type
์ ํ์
๋ฌธ๋งฅ์ ์ฌ์ฉํ export๋ง ์ ๊ณตํ๋ฉฐ, ์ด ๋ํ TypeScript์ ์ถ๋ ฅ๋ฌผ์์ ์ ๊ฑฐ๋ฉ๋๋ค.
ํด๋์ค๋ ๋ฐํ์์ ๊ฐ์ ๊ฐ์ง๊ณ ์๊ณ ๋์์ธ-ํ์์ ํ์
์ด ์์ผ๋ฉฐ ์ฌ์ฉ์ ์ํฉ์-๋ฐ๋ผ ๋ค๋ฅด๋ค๋ ๊ฒ์ ์ ์ํด์ผ ํฉ๋๋ค.
ํด๋์ค๋ฅผ import ํ๊ธฐ ์ํด import type
์ ์ฌ์ฉํ๋ฉด, ํ์ฅ ๊ฐ์ ๊ฒ์ ํ ์ ์์ต๋๋ค.
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.
// ...
}
์ด์ ์ Flow๋ฅผ ์ฌ์ฉํด๋ณธ ์ ์ด ์๋ค๋ฉด, ์ด ๊ตฌ๋ฌธ์ ์๋นํ ์ ์ฌํฉ๋๋ค. ํ ๊ฐ์ง ์ฐจ์ด์ ์ ์ฝ๋๊ฐ ๋ชจํธํด ๋ณด์ด์ง ์๋๋ก ๋ช ๊ฐ์ง ์ ํ์ ๋์๋ค๋ ๊ฒ์ ๋๋ค.
// '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 type
๊ณผ ํจ๊ป, TypeScript 3.8์ ๋ฐํ์ ์ ์ฌ์ฉ๋์ง ์๋ import์์ ๋ฐ์ํ๋ ์์
์ ์ ์ดํ๊ธฐ ์ํด ์๋ก์ด ์ปดํ์ผ๋ฌ ํ๋๊ทธ๋ฅผ ์ถ๊ฐํฉ๋๋ค: importsNotUsedAsValues
.
์ด ํ๋๊ทธ๋ 3 ๊ฐ์ง ๋ค๋ฅธ ๊ฐ์ ๊ฐ์ง๋๋ค:
remove
: ์ด๋ imports๋ฅผ ์ ๊ฑฐํ๋ ํ์ฌ ๋์์ด๋ฉฐ, ๊ณ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์๋ํ ๊ฒ์ด๋ฉฐ, ๊ธฐ์กด ๋์์ ๋ฐ๊พธ๋ ๋ณํ๊ฐ ์๋๋๋ค.preserve
: ์ด๋ ์ฌ์ฉ๋์ง ์๋ ๊ฐ๋ค์ ๋ชจ๋ ๋ณด์กดํฉ๋๋ค. ์ด๋ก ์ธํด imports/side-effects๊ฐ ๋ณด์กด๋ ์ ์์ต๋๋ค.error
: ์ด๋ ๋ชจ๋ (preserve
option ์ฒ๋ผ) ๋ชจ๋ imports๋ฅผ ๋ณด์กดํ์ง๋ง, import ๊ฐ์ด ํ์ ์ผ๋ก๋ง ์ฌ์ฉ๋ ๊ฒฝ์ฐ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค. ์ด๋ ์ค์๋ก ๊ฐ์ importํ์ง ์์ง๋ง ์ฌ์ด๋ ์ดํฉํธ import๋ฅผ ๋ช ์์ ์ผ๋ก ๋ง๋ค๊ณ ์ถ์ ๋ ์ ์ฉํฉ๋๋ค.
์ด ๊ธฐ๋ฅ์ ๋ํ ๋ ์์ธํ ์ ๋ณด๋, import type
์ ์ธ์ด ์ฌ์ฉ๋ ์ ์๋ ๋ฒ์๋ฅผ ํ๋ํ๋ pull request, ์ ๊ด๋ จ๋ ๋ณ๊ฒฝ ์ฌํญ์์ ์ฐพ์ ์ ์์ต๋๋ค.
TypeScript 3.8 ์ ECMAScript์ stage-3 ํด๋์ค ํ๋ ์ ์์ ๋น๊ณต๊ฐ ํ๋๋ฅผ ์ง์ํฉ๋๋ค.
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' ํด๋์ค ์ธ๋ถ์์ ์ ๊ทผํ ์ ์์ต๋๋ค.
// ์ด๋ ๋น๊ณต๊ฐ ์๋ณ์๋ฅผ ๊ฐ์ง๊ธฐ ๋๋ฌธ์
๋๋ค.
์ผ๋ฐ์ ์ธ ํ๋กํผํฐ๋ค(private
์ง์ ์๋ก ์ ์ธํ ๊ฒ๋)๊ณผ ๋ฌ๋ฆฌ, ๋น๊ณต๊ฐ ํ๋๋ ๋ช ๊ฐ์ง ๋ช
์ฌํด์ผ ํ ๊ท์น์ด ์์ต๋๋ค.
๊ทธ์ค ๋ช๋ช์:
- ๋น๊ณต๊ฐ ํ๋๋
#
๋ฌธ์๋ก ์์ํฉ๋๋ค. ๋๋๋ก ์ด๋ฅผ ๋น๊ณต๊ฐ ์ด๋ฆ(private names) ์ด๋ผ๊ณ ๋ถ๋ฆ ๋๋ค. - ๋ชจ๋ ๋น๊ณต๊ฐ ํ๋ ์ด๋ฆ์ ์ด๋ฅผ ํฌํจํ ํด๋์ค ๋ฒ์์์ ์ ์ผํฉ๋๋ค.
public
๋๋private
๊ฐ์ TypeScript ์ ๊ทผ ์ง์ ์๋ ๋น๊ณต๊ฐ ํ๋๋ก ์ฌ์ฉ๋ ์ ์์ต๋๋ค.- JS ์ฌ์ฉ์๋ก๋ถํฐ๋ ๋น๊ณต๊ฐ ํ๋๋ ์ด๋ฅผ ํฌํจํ ํด๋์ค ๋ฐ์์ ์ ๊ทผํ๊ฑฐ๋ ํ์งํ ์ ์์ต๋๋ค! ๋๋๋ก ์ด๋ฅผ ๊ฐํ ๋น๊ณต๊ฐ(hard privacy) ๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
"๊ฐํ" ๋น๊ณต๊ฐ์ ๋ณ๋๋ก, ๋น๊ณต๊ฐ ํ๋์ ๋ ๋ค๋ฅธ ์ฅ์ ์ ์ ์ผํ๋ค๋ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค์ด, ์ผ๋ฐ์ ์ธ ํ๋กํผํฐ ์ ์ธ์ ํ์ํด๋์ค์์ ๋ฎ์ด์ฐ๊ธฐ ์ฝ์ต๋๋ค.
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' ์ถ๋ ฅ
๋น๊ณต๊ฐ ํ๋์์๋, ํฌํจํ๊ณ ์๋ ํด๋์ค์์ ๊ฐ๊ฐ์ ํ๋ ์ด๋ฆ์ด ์ ์ผํ๊ธฐ ๋๋ฌธ์ ์ด์ ๋ํด ๊ฑฑ์ ํ์ง ์์๋ ๋ฉ๋๋ค.
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' ์ถ๋ ฅ
์์ ๋๋ฉด ์ข์ ๋ ๋ค๋ฅธ ์ ์ ๋ค๋ฅธ ํ์
์ผ๋ก ๋น๊ณต๊ฐ ํ๋์ ์ ๊ทผํ๋ฉด TypeError
๋ฅผ ๋ฐ์ํ๋ค๋ ๊ฒ์
๋๋ค.
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));
๋ง์๋ง์ผ๋ก, ๋ชจ๋ ์ผ๋ฐ .js
ํ์ผ ์ฌ์ฉ์๋ค์ ๊ฒฝ์ฐ, ๋น๊ณต๊ฐ ํ๋๋ ํญ์ ํ ๋น๋๊ธฐ ์ ์ ์ ์ธ๋์ด์ผ ํฉ๋๋ค.
class C {
// '#foo' ์ ์ธ์ด ์์ต๋๋ค.
// :(
constructor(foo: number) {
// SyntaxError!
// '#foo'๋ ์ฐ์ฌ์ง๊ธฐ ์ ์ ์ ์ธ๋์ด์ผ ํฉ๋๋ค.
this.#foo = foo;
}
}
JavaScript๋ ํญ์ ์ฌ์ฉ์๋ค์๊ฒ ์ ์ธ๋์ง ์์ ํ๋กํผํฐ์ ์ ๊ทผ์ ํ์ฉํ์ง๋ง, TypeScript๋ ํญ์ ํด๋์ค ํ๋กํผํฐ ์ ์ธ์ ์๊ตฌํ์ต๋๋ค.
๋น๊ณต๊ฐ ํ๋๋, .js
๋๋ .ts
ํ์ผ์์ ๋์ํ๋์ง ์๊ด์์ด ํญ์ ์ ์ธ์ด ํ์ํฉ๋๋ค.
class C {
/** @type {number} */
#foo;
constructor(foo: number) {
// ๋์ํฉ๋๋ค.
this.#foo = foo;
}
}
๊ตฌํ์ ๋ํ ๋ ๋ง์ ์ ๋ณด๋, the original pull request๋ฅผ ์ฐธ๊ณ ํ์ธ์
์ด๋ฏธ TypeScript ์ ์ ๋ก์ ์ด๋ค ์ข
๋ฅ์ ๋น๊ณต๊ฐ๋ฅผ ์ฌ์ฉํด์ผ ํ๋์ง์ ๋ํ ๋ง์ ์ง๋ฌธ์ ๋ฐ์์ต๋๋ค: ์ฃผ๋ก, "private
ํค์๋๋ฅผ ์ฌ์ฉํด์ผ ํ๋์ ์๋๋ฉด ECMAScript์ ํด์/์ฐ๋ฌผ (#
) ๋น๊ณต๊ฐ ํ๋๋ฅผ ์ฌ์ฉํด์ผ ํ๋์?"
์ํฉ๋ง๋ค ๋ค๋ฆ
๋๋ค!
ํ๋กํผํฐ์์, TypeScript์ private
์ง์ ์๋ ์์ ํ ์ง์์ง๋๋ค - ์ด๋ ๋ฐํ์์์๋ ์์ ํ ์ผ๋ฐ ํ๋กํผํฐ์ฒ๋ผ ๋์ํ๋ฉฐ ์ด๊ฒ์ด private
์ง์ ์๋ก ์ ์ธ๋์๋ค๊ณ ์๋ฆด ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
private
ํค์๋๋ฅผ ์ฌ์ฉํ ๋, ๋น๊ณต๊ฐ๋ ์ค์ง ์ปดํ์ผ-ํ์/๋์์ธ-ํ์์๋ง ์ํ๋๋ฉฐ, JavaScript ์ฌ์ฉ์์๊ฒ๋ ์ ์ ์ผ๋ก ์๋-๊ธฐ๋ฐ์
๋๋ค.
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'
์ด ๊ฐ์ ์ข ๋ฅ์ "์ฝํ ๋น๊ณต๊ฐ(soft privacy)"๋ ์ฌ์ฉ์๊ฐ API์ ์ ๊ทผํ ์ ์๋ ์ํ์์ ์ผ์์ ์ผ๋ก ์์ ์ ํ๋ ๋ฐ ๋์์ด ๋๋ฉฐ, ์ด๋ค ๋ฐํ์์์๋ ๋์ํฉ๋๋ค.
๋ฐ๋ฉด์, ECMAScript์ #
๋น๊ณต๊ฐ๋ ์๋ฒฝํ๊ฒ ํด๋์ค ๋ฐ์์ ์ ๊ทผ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
class C {
#foo = 10;
}
console.log(new C().#foo); // SyntaxError
// ~~~~
// TypeScript ๋ ์ค๋ฅ๋ฅผ ๋ณด๊ณ ํ๋ฉฐ *๋ํ*
// ๋ฐํ์์๋ ๋์ํ์ง ์์ต๋๋ค.
console.log(new C()["#foo"]); // undefined ์ถ๋ ฅ
// ~~~~~~~~~~~~~~~
// TypeScript ๋ 'noImplicitAny' ํ์์ ์ค๋ฅ๋ฅผ ๋ณด๊ณ ํ๋ฉฐ
// `undefined`๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
์ด๋ฐ ๊ฐํ ๋น๊ณต๊ฐ(hard privacy)๋ ์๋ฌด๋ ๋ด๋ถ๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ์๊ฒฉํ๊ฒ ๋ณด์ฅํ๋๋ฐ ์ ์ฉํฉ๋๋ค. ๋ง์ฝ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ฑ์์ผ ๊ฒฝ์ฐ, ๋น๊ณต๊ฐ ํ๋๋ฅผ ์ ๊ฑฐํ๊ฑฐ๋ ์ด๋ฆ์ ๋ฐ๊พธ๋ ๊ฒ์ด ๊ธ๊ฒฉํ ๋ณํ๋ฅผ ์ด๋์๋ ์๋ฉ๋๋ค.
์ธ๊ธํ๋ฏ์ด, ๋ค๋ฅธ ์ฅ์ ์ ECMAScript์ #
๋น๊ณต๊ฐ๊ฐ ์ง์ง ๋น๊ณต๊ฐ์ด๊ธฐ ๋๋ฌธ์ ์๋ธํด๋์ฑ์ ์ฝ๊ฒ ํ ์ ์๋ค๋ ๊ฒ์
๋๋ค.
ECMAScript #
๋น๊ณต๊ฐ ํ๋๋ฅผ ์ฌ์ฉํ๋ฉด, ์ด๋ค ์๋ธ ํด๋์ค๋ ํ๋ ๋ค์ด๋ฐ ์ถฉ๋์ ๋ํด ๊ฑฑ์ ํ ํ์๊ฐ ์์ต๋๋ค.
TypeScript์ private
ํ๋กํผํฐ ์ ์ธ์์๋, ์ฌ์ฉ์๋ ์ฌ์ ํ ์์ ํด๋์ค์ ์ ์ธ๋ ํ๋กํผํฐ๋ฅผ ์ง๋ฐ์ง ์๋๋ก ์ฃผ์ํด์ผ ํฉ๋๋ค.
ํ ๊ฐ์ง ๋ ์๊ฐํด๋ด์ผ ํ ๊ฒ์ ์ฝ๋๊ฐ ์คํ๋๊ธฐ๋ฅผ ์๋ํ๋ ๊ณณ์
๋๋ค.
ํ์ฌ TypeScript๋ ์ด ๊ธฐ๋ฅ์ ECMAScript 2015 (ES6) ์ด์ ๋ฒ์ ์ ๋์์ผ๋ก ํ์ง ์์ผ๋ฉด ์ง์ํ ์ ์์ต๋๋ค.
์ด๋ ํ์ ๋ ๋ฒจ ๊ตฌํ์ด ๋น๊ณต๊ฐ๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํด WeakMap
์ ์ฌ์ฉํ๋๋ฐ, WeakMap
์ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ์์ผํค์ง ์๋๋ก ํด๋ฆฌํ๋ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๋ฐ๋ฉด, TypeScript์ private
-์ ์ธ ํ๋กํผํฐ๋ ๋ชจ๋ ๋์์์ ๋์ํฉ๋๋ค- ECMAScript3์์๋!
๋ง์ง๋ง ๊ณ ๋ ค ์ฌํญ์ ์๋ ์ผ์ ์์ต๋๋ค: private
ํ๋กํผํฐ๋ ๋ค๋ฅธ ์ด๋ค ํ๋กํผํฐ์ ๋ค๋ฅด์ง ์๊ธฐ ๋๋ฌธ์, ์ด๋ค ๋ฐํ์์ ๋์์ผ๋ก ํ๋จ ๋ค๋ฅธ ํ๋กํผํฐ์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ ๊ทผ ์๋๊ฐ ๋น ๋ฅผ ์ ์์ต๋๋ค.
๋ฐ๋ฉด์, #
๋น๊ณต๊ฐ ํ๋๋ WeakMap
์ ์ด์ฉํด ๋ค์ด ๋ ๋ฒจ ๋๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ ์๋๊ฐ ๋๋ ค์ง ์ ์์ต๋๋ค.
์ด๋ค ๋ฐํ์์ #
๋น๊ณต๊ฐ ํ๋ ๊ตฌํ์ ์ต์ ํ ํ๊ณ , ๋ ๋น ๋ฅธ WeakMap
์ ๊ตฌํํ๊ณ ์ถ์ ์ ์์ง๋ง, ๋ชจ๋ ๋ฐํ์์์ ๊ทธ๋ ์ง ์์ ์ ์์ต๋๋ค.
๋ค๋ฅธ ๋ชจ๋์ ๋ชจ๋ ๋ฉค๋ฒ๋ฅผ ํ๋์ ๋ฉค๋ฒ๋ก ๋ด๋ณด๋ด๋ ๋จ์ผ ์ง์ ์ ์ ๊ฐ๋ ๊ฒ์ ์ข ์ข ์ผ๋ฐ์ ์ ๋๋ค.
import * as utilities from "./utilities.js";
export { utilities };
์ด๋ ๋งค์ฐ ์ผ๋ฐ์ ์ด์ด์ ECMAScript2020์ ์ต๊ทผ์ ์ด ํจํด์ ์ง์ํ๊ธฐ ์ํด์ ์๋ก์ด ๊ตฌ๋ฌธ์ ์ถ๊ฐํ์ต๋๋ค.
export * as utilities from "./utilities.js";
์ด๊ฒ์ JavaScript์ ๋ํ ํ๋ฅญํ ์ถ์ ์ง์ ํฅ์์ด๋ฉฐ, TypeScript 3.8์ ์ด ๊ตฌ๋ฌธ์ ์ง์ํฉ๋๋ค.
๋ชจ๋ ๋์์ด es2020
์ด์ ์ธ ๊ฒฝ์ฐ, TypeScript๋ ์ฒซ ๋ฒ์งธ ์ค์ ์ฝ๋ ์ค๋ํซ์ ๋ฐ๋ผ์ ๋ฌด์ธ๊ฐ๋ฅผ ์ถ๋ ฅํ ๊ฒ์
๋๋ค.
TypeScript 3.8์ "์ต์์-๋ ๋ฒจ await
"์ด๋ผ๋ ํธ๋ฆฌํ ECMAScript ๊ธฐ๋ฅ์ ์ง์ํฉ๋๋ค.
JavaScript ์ฌ์ฉ์๋ await
์ ์ฌ์ฉํ๊ธฐ ์ํด async
ํจ์๋ฅผ ๋์
ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ผ๋ฉฐ, ์ด๋ฅผ ์ ์ํ ํ ์ฆ์ ํจ์๋ฅผ ํธ์ถํฉ๋๋ค.
async function main() {
const response = await fetch("...");
const greeting = await response.text();
console.log(greeting);
}
main()
.catch(e => console.error(e))
์ด์ ์ JavaScript(์ ์ฌํ ๊ธฐ๋ฅ์ ๊ฐ์ง ๋๋ถ๋ถ์ ๋ค๋ฅธ ์ธ์ด๋ค๊ณผ ํจ๊ป)์์ await
์ async
ํจ์ ๋ด์์ ๋ง ํ์ฉ๋์๊ธฐ ๋๋ฌธ์
๋๋ค.
ํ์ง๋ง ์ต์์-๋ ๋ฒจ await
๋ก, ์ฐ๋ฆฌ๋ ๋ชจ๋์ ์ต์์ ๋ ๋ฒจ์์ await
์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
const response = await fetch("...");
const greeting = await response.text();
console.log(greeting);
// ๋ชจ๋์ธ์ง ํ์ธ
export {};
์ ์ํ ์ ์ด ์์ต๋๋ค: ์ต์์-๋ ๋ฒจ await
์ module์ ์ต์์ ๋ ๋ฒจ์์๋ง ๋์ํ๋ฉฐ, ํ์ผ์ TypeScript๊ฐ import
๋ export
๋ฅผ ์ฐพ์ ๋์๋ง ๋ชจ๋๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์ผ๋ถ ๊ธฐ๋ณธ์ ์ธ ๊ฒฝ์ฐ์ export {}
์ ๊ฐ์ ๋ณด์ผ๋ฌ ํ๋ ์ดํธ๋ฅผ ์์ฑํ์ฌ ์ด๋ฅผ ํ์ธํ ํ์๊ฐ ์์ต๋๋ค.
์ด๋ฌํ ๊ฒฝ์ฐ๊ฐ ์์๋๋ ๋ชจ๋ ํ๊ฒฝ์์ ์ต์์ ๋ ๋ฒจ await
์ ๋์ํ์ง ์์ ์ ์์ต๋๋ค.
ํ์ฌ, target
์ปดํ์ผ๋ฌ ์ต์
์ด es2017
์ด์์ด๊ณ , module
์ด esnext
๋๋ system
์ธ ๊ฒฝ์ฐ์๋ง ์ต์์ ๋ ๋ฒจ await
์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ช๋ช ํ๊ฒฝ๊ณผ ๋ฒ๋ค๋ฌ๋ด์์์ ์ง์์ ์ ํ์ ์ผ๋ก ์๋ํ๊ฑฐ๋ ์คํ์ ์ง์์ ํ์ฑํํด์ผ ํ ์๋ ์์ต๋๋ค.
๊ตฌํ์ ๊ดํ ๋ ์์ธํ ์ ๋ณด๋ the original pull request์ ํ์ธํ์ธ์.
TypeScript 3.8์ es2020
์ module
๊ณผ target
์ต์
์ผ๋ก ์ง์ํฉ๋๋ค.
์ด๋ฅผ ํตํด ์ ํ์ ์ฒด์ด๋ (optional chaining), nullish ๋ณํฉ (nullish coalescing), export * as ns
๊ทธ๋ฆฌ๊ณ ๋์ ์ธ import(...)
๊ตฌ๋ฌธ๊ณผ ๊ฐ์ ECMAScript 2020 ๊ธฐ๋ฅ์ด ์ ์ง๋ฉ๋๋ค.
๋ํ bigint
๋ฆฌํฐ๋ด์ด esnext
์๋์ ์์ ์ ์ธ target
์ ๊ฐ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
TypeScript 3.8๋ allowJs
ํ๋๊ทธ๋ฅผ ์ฌ์ฉํ์ฌ JavaScript ํ์ผ์ ์ง์ํ๊ณ checkJs
์ต์
์ด๋ // @ts-check
์ฃผ์์ .js
ํ์ผ ๋งจ ์์ ์ถ๊ฐํ์ฌ JavaScript ํ์ผ์ ํ์
-๊ฒ์ฌ๋ฅผ ์ง์ํฉ๋๋ค.
JavaScript ํ์ผ์๋ ํ์ -๊ฒ์ฌ๋ฅผ ์ํ ์ ์ฉ ๊ตฌ๋ฌธ์ด ์๊ธฐ ๋๋ฌธ์ TypeScript๋ JSDoc์ ํ์ฉํฉ๋๋ค. TypeScript 3.8์ ํ๋กํผํฐ์ ๋ํ ๋ช ๊ฐ์ง ์๋ก์ด JSDoc ํ๊ทธ๋ฅผ ์ธ์ํฉ๋๋ค.
๋จผ์ ์ ๊ทผ ์ง์ ์์
๋๋ค: @public
, @private
๊ทธ๋ฆฌ๊ณ @protected
์
๋๋ค.
์ด ํ๊ทธ๋ค์ TypeScript ๋ด์์ ๊ฐ๊ฐ public
, private
, protected
์ ๋์ผํ๊ฒ ๋์ํฉ๋๋ค.
// @ts-check
class Foo {
constructor() {
/** @private */
this.stuff = 100;
}
printStuff() {
console.log(this.stuff);
}
}
new Foo().stuff;
// ~~~~~
// ์ค๋ฅ! 'stuff' ํ๋กํผํฐ๋ private ์ด๊ธฐ ๋๋ฌธ์ ์ค์ง 'Foo' ํด๋์ค ๋ด์์๋ง ์ ๊ทผ์ด ๊ฐ๋ฅํฉ๋๋ค.
@public
์ ํญ์ ์์์ ์ด๋ฉฐ ์๋ต๋ ์ ์์ง๋ง, ์ด๋์๋ ํด๋น ํ๋กํผํฐ์ ์ ๊ทผ ๊ฐ๋ฅ์ ์๋ฏธํฉ๋๋ค.@private
์ ์ค์ง ํ๋กํผํฐ๋ฅผ ํฌํจํ๋ ํด๋์ค ๋ด์์ ํด๋น ํ๋กํผํฐ ์ฌ์ฉ ๊ฐ๋ฅ์ ์๋ฏธํฉ๋๋ค.@protected
๋ ํ๋กํผํฐ๋ฅผ ํฌํจํ๋ ํด๋์ค์ ํ์๋ ๋ชจ๋ ํ์ ํด๋์ค๋ด์์ ํด๋น ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ ์ ์์ง๋ง, ํฌํจํ๋ ํด๋์ค์ ์ธ์คํด์ค๋ ํด๋น ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ค์์ผ๋ก @readonly
์ง์ ์๋ฅผ ์ถ๊ฐํ์ฌ ํ๋กํผํฐ๊ฐ ์ด๊ธฐํ ๊ณผ์ ๋ด์์๋ง ๊ฐ์ด ์ฐ์ด๋ ๊ฒ์ ๋ณด์ฅํฉ๋๋ค.
// @ts-check
class Foo {
constructor() {
/** @readonly */
this.stuff = 100;
}
writeToStuff() {
this.stuff = 200;
// ~~~~~
// 'stuff'๋ ์ฝ๊ธฐ-์ ์ฉ(read-only) ํ๋กํผํฐ์ด๊ธฐ ๋๋ฌธ์ ํ ๋นํ ์ ์์ต๋๋ค.
}
}
new Foo().stuff++;
// ~~~~~
// 'stuff'๋ ์ฝ๊ธฐ-์ ์ฉ(read-only) ํ๋กํผํฐ์ด๊ธฐ ๋๋ฌธ์ ํ ๋นํ ์ ์์ต๋๋ค.
TypeScript 3.8์์๋ node_modules
์ ๋ณ๊ฒฝ์ฌํญ์ ํจ์จ์ ์ผ๋ก ์์งํ๋๋ฐ ์ค์ํ ์๋ก์ด ๋๋ ํฐ๋ฆฌ ๊ฐ์ ์ ๋ต์ ์ ๊ณตํฉ๋๋ค.
๋ฆฌ๋
์ค์ ๊ฐ์ ์ด์์ฒด์ ์์ TypeScript๋ node_modules
์ ๋๋ ํฐ๋ฆฌ ์์ณ(ํ์ผ ์์ณ์๋ ๋ฐ๋๋ก)๋ฅผ ์ค์นํ๊ณ , ์์กด์ฑ ๋ณํ๋ฅผ ๊ฐ์งํ๊ธฐ ์ํด ๋ง์ ํ์ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ค์นํฉ๋๋ค.
์๋ํ๋ฉด ์ฌ์ฉ ๊ฐ๋ฅํ ํ์ผ ์์ณ์ ์๋ ์ข
์ข
node_modules
์ ํ์ผ ์์ ์ํด ๊ฐ๋ ค์ง๊ธฐ ๋๋ฌธ์ด๊ณ , ์ถ์ ํ ๋๋ ํฐ๋ฆฌ ์๊ฐ ์ ๊ธฐ ๋๋ฌธ์
๋๋ค.
TypeScript์ ์ด์ ๋ฒ์ ์ ํด๋์ ๋๋ ํฐ๋ฆฌ ์์ณ๋ฅผ ์ฆ์ ์ค์นํ๋ฉฐ, ์ด๊ธฐ์๋ ๊ด์ฐฎ์ ๊ฒ๋๋ค; ํ์ง๋ง, npm install ํ ๋, node_modules
์์์ ๋ง์ ์ผ๋ค์ด ๋ฐ์ํ ๊ฒ์ด๊ณ , TypeScript๋ฅผ ์๋ํ์ฌ, ์ข
์ข
์๋ํฐ ์ธ์
์ ์์ฃผ ๋๋ฆฌ๊ฒ ๋ง๋ญ๋๋ค.
์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด, TypeScript 3.8์ ๋๋ ํฐ๋ฆฌ ์์ณ๋ฅผ ์ค์นํ๊ธฐ ์ ์ ์กฐ๊ธ ๊ธฐ๋ค๋ ค์ ๋ณ๋์ฑ์ด ๋์ ๋๋ ํฐ๋ฆฌ์๊ฒ ์์ ๋ ์ ์๋ ์๊ฐ์ ์ค๋๋ค.
์๋ํ๋ฉด ๋ชจ๋ ํ๋ก์ ํธ๋ ๋ค๋ฅธ ์ ๋ต์์ ๋ ์ ์๋ํ ์ ์๊ณ , ์ด ์๋ก์ด ๋ฐฉ๋ฒ์ ๋น์ ์ ์์
ํ๋ฆ์์๋ ์ ๋ง์ง ์์ ์ ์์ต๋๋ค. TypeScript 3.8์ ํ์ผ๊ณผ ๋๋ ํฐ๋ฆฌ๋ฅผ ๊ฐ์ํ๋๋ฐ ์ด๋ค ๊ฐ์ ์ ๋ต์ ์ฌ์ฉํ ์ง ์ปดํ์ผ๋ฌ/์ธ์ด ์๋น์ค์ ์๋ ค์ค ์ ์๋๋ก tsconfig.json
๊ณผ jsconfig.json
์ watchOptions
๋ ์๋ก์ด ํ๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
{
// ์ผ๋ฐ์ ์ธ ์ปดํ์ผ๋ฌ ์ต์
๋ค
"compilerOptions": {
"target": "es2020",
"moduleResolution": "node",
// ...
},
// NEW: ํ์ผ/๋๋ ํฐ๋ฆฌ ๊ฐ์๋ฅผ ์ํ ์ต์
"watchOptions": {
// ํ์ผ๊ณผ ๋๋ ํฐ๋ฆฌ์ ๋ค์ดํฐ๋ธ ํ์ผ ์์คํ
์ด๋ฒคํธ ์ฌ์ฉ
"watchFile": "useFsEvents",
"watchDirectory": "useFsEvents",
// ์
๋ฐ์ดํธ๊ฐ ๋น๋ฒํ ๋
// ์
๋ฐ์ดํธํ๊ธฐ ์ํด ๋ ์์ฃผ ํ์ผ์ ํด๋ง
"fallbackPolling": "dynamicPriority"
}
}
watchOptions
๋ ๊ตฌ์ฑํ ์ ์๋ 4๊ฐ์ง ์๋ก์ด ์ต์
์ด ํฌํจ๋์ด ์์ต๋๋ค.
watchFile
: ๊ฐ ํ์ผ์ ๊ฐ์ ๋ฐฉ๋ฒ ์ ๋ต. ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํ ์ ์์ต๋๋ค:fixedPollingInterval
: ๊ณ ์ ๋ ๊ฐ๊ฒฉ์ผ๋ก ๋ชจ๋ ํ์ผ์ ๋ณ๊ฒฝ์ 1์ด์ ์ฌ๋ฌ ๋ฒ ๊ฒ์ฌํฉ๋๋ค.priorityPollingInterval
: ๋ชจ๋ ํ์ผ์ ๋ณ๊ฒฝ์ 1์ด์ ์ฌ๋ฌ ๋ฒ ๊ฒ์ฌํฉ๋๋ค, ํ์ง๋ง ํด๋ฆฌ์คํฑ์ ์ฌ์ฉํ์ฌ ํน์ ํ์ ์ ํ์ผ์ ๋ค๋ฅธ ํ์ ์ ํ์ผ๋ณด๋ค ๋ ์์ฃผ ๊ฒ์ฌํฉ๋๋ค.dynamicPriorityPolling
: ๋์ ํ๋ฅผ ์ฌ์ฉํ์ฌ ๋-์์ฃผ ์์ ๋ ํ์ผ์ ์ ๊ฒ ๊ฒ์ฌํฉ๋๋ค.useFsEvents
(๋ํดํธ): ํ์ผ ๋ณํ์ ์ด์์ฒด์ /ํ์ผ ์์คํ ์ ๋ค์ดํฐ๋ธ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค.useFsEventsOnParentDirectory
: ํ์ผ์ ํฌํจํ๊ณ ์๋ ๋๋ ํฐ๋ฆฌ ๋ณ๊ฒฝ์ ๊ฐ์งํ ๋, ์ด์์ฒด์ /ํ์ผ ์์คํ ์ ๋ค์ดํฐ๋ธ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค. ํ์ผ ์์ณ๋ฅผ ์ ๊ฒ ์ฌ์ฉํ ์ ์์ง๋ง, ๋ ์ ํํ ์ ์์ต๋๋ค.
watchDirectory
: ์ฌ๊ท์ ์ธ ํ์ผ-๊ฐ์ ๊ธฐ๋ฅ์ด ์๋ ์์คํ ์์์ ์ ์ฒด ๋๋ ํฐ๋ฆฌ ํธ๋ฆฌ๊ฐ ๊ฐ์๋๋ ์ ๋ต. ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํ ์ ์์ต๋๋ค:fixedPollingInterval
: ๊ณ ์ ๋ ๊ฐ๊ฒฉ์ผ๋ก ๋ชจ๋ ๋๋ ํฐ๋ฆฌ์ ๋ณ๊ฒฝ์ 1์ด์ ์ฌ๋ฌ ๋ฒ ๊ฒ์ฌํฉ๋๋ค.dynamicPriorityPolling
: ๋์ ํ๋ฅผ ์ฌ์ฉํ์ฌ ๋-์์ฃผ ์์ ๋ ๋๋ ํฐ๋ฆฌ๋ ์ ๊ฒ ๊ฒ์ฌํฉ๋๋ค.useFsEvents
(๋ํดํธ): ๋๋ ํฐ๋ฆฌ ๋ณ๊ฒฝ์ ์ด์์ฒด์ /ํ์ผ ์์คํ ์ ๋ค์ดํฐ๋ธ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
fallbackPolling
: ํ์ผ ์์คํ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํ ๋, ์ด ์ต์ ์ ์์คํ ์ด ๋ค์ดํฐ๋ธ ํ์ผ ์์ณ๊ฐ ๋ถ์กฑํ๊ฑฐ๋/ํน์ ์ง์ํ์ง ์์ ๋, ์ฌ์ฉ๋๋ ํด๋ง ์ ๋ต์ ์ง์ ํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํ ์ ์์ต๋๋ค.fixedPollingInterval
: (์๋ฅผ ์ฐธ์กฐํ์ธ์.)priorityPollingInterval
: (์๋ฅผ ์ฐธ์กฐํ์ธ์.)dynamicPriorityPolling
: (์๋ฅผ ์ฐธ์กฐํ์ธ์.)
synchronousWatchDirectory
: ๋๋ ํฐ๋ฆฌ์ ์ฐ๊ธฐ๋ ๊ฐ์๋ฅผ ๋นํ์ฑํํฉ๋๋ค. ์ฐ๊ธฐ๋ ๊ฐ์๋ ๋ง์ ํ์ผ์ด ํ ๋ฒ์ ๋ณ๊ฒฝ๋ ๋ ์ ์ฉํฉ๋๋ค (์๋ฅผ ๋ค์ด,npm install
์ ์คํํ์ฌnode_modules
์ ๋ณ๊ฒฝ), ํ์ง๋ง ๋-์ผ๋ฐ์ ์ธ ์ค์ ์ ์ํด ๋นํ์ฑํํ ์๋ ์์ต๋๋ค.
์ด ๋ณ๊ฒฝ์ ๋ ์์ธํ ๋ด์ฉ์ Github์ผ๋ก ์ด๋ํ์ฌ the pull request๋ฅผ ์ฝ์ด๋ณด์ธ์.
TypeScript 3.8์ ์๋ก์ด ์ปดํ์ผ๋ฌ ์ต์
assumeChangesOnlyAffectDirectDepencies
์ ์ ๊ณตํฉ๋๋ค.
์ด ์ต์
์ด ํ์ฑํ๋๋ฉด, TypeScript๋ ์ ๋ง๋ก ์ํฅ์ ๋ฐ์ ํ์ผ๋ค์ ์ฌ๊ฒ์ฌ/์ฌ๋น๋ํ์ง์๊ณ , ๋ณ๊ฒฝ๋ ํ์ผ๋ฟ๋ง ์๋๋ผ ์ง์ import ํ ํ์ผ๋ง ์ฌ๊ฒ์ฌ/์ฌ๋น๋ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด fileA.ts
๋ฅผ import ํ fileB.ts
๋ฅผ import ํ fileC.ts
๋ฅผ import ํ fileD.ts
๋ฅผ ์ดํด๋ด
์๋ค:
fileA.ts <- fileB.ts <- fileC.ts <- fileD.ts
--watch
๋ชจ๋์์๋, fileA.ts
์ ๋ณ๊ฒฝ์ด fileB.ts
, fileC.ts
๊ทธ๋ฆฌ๊ณ fileD.ts
๋ฅผ TypeScript๊ฐ ์ฌ-๊ฒ์ฌํด์ผ ํ๋ค๋ ์๋ฏธ์
๋๋ค.
assumeChangesOnlyAffectDirectDependencies
์์๋ fileA.ts
์ ๋ณ๊ฒฝ์ fileA.ts
์ fileB.ts
๋ง ์ฌ-๊ฒ์ฌํ๋ฉด ๋ฉ๋๋ค.
Visual Studio Code์ ๊ฐ์ ์ฝ๋ ๋ฒ ์ด์ค์์๋, ํน์ ํ์ผ์ ๋ณ๊ฒฝ์ ๋ํด ์ฝ 14์ด์์ ์ฝ 1์ด๋ก ์ฌ๋น๋ ์๊ฐ์ ์ค์ฌ์ฃผ์์ต๋๋ค.
์ด ์ต์
์ ๋ชจ๋ ์ฝ๋ ๋ฒ ์ด์ค์์ ์ถ์ฒํ๋ ๊ฒ์ ์๋์ง๋ง, ํฐ ์ฝ๋ ๋ฒ ์ด์ค๋ฅผ ๊ฐ์ง๊ณ ์๊ณ , ๋์ค๊น์ง ์ ์ฒด ํ๋ก์ ํธ ์ค๋ฅ๋ฅผ ๊ธฐ๊บผ์ด ์ฐ๊ธฐํ๊ฒ ๋ค๋ฉด (์๋ฅผ ๋ค์ด, tsconfig.fullbuild.json
์ด๋ CI๋ฅผ ํตํ ์ ์ฉ ๋น๋) ํฅ๋ฏธ๋ก์ธ ๊ฒ์
๋๋ค.
๋ ์์ธํ ๋ด์ฉ์ the original pull request์์ ๋ณด์ค ์ ์์ต๋๋ค.