์ถ๋ก ๊ณผ Promise.all
๊ฐ์ (Improvements in Inference and Promise.all
)
์ต์ ๋ฒ์ ์ TypeScript(์ฝ 3.7)๋ Promise.all
๋ฐ Promise.race
์ ๊ฐ์ ํจ์ ์ ์ธ์ด ์
๋ฐ์ดํธ๋์์ต๋๋ค.
์ํ๊น๊ฒ๋, ํนํ null
๋๋ undefined
์ ๊ฐ์ ํผํฉํ ๋, ์ฝ๊ฐ์ ํ๊ท๊ฐ ๋ฐ์ํ์ต๋๋ค.
ts
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' ์ผ ๊ฒ์ ๋๋ค.}
์ด ๋์์ ์ด์ํฉ๋๋ค!
sealExhibit
๊ฐ undefined
๋ฅผ ํฌํจํ๋ ๊ฒ์ ์ด๋ป๊ฒ๋ lion
ํ์
์ undefined
๋ฅผ ์ฃผ์
ํฉ๋๋ค.
Jack Bates์ pull request ๋๋ถ์, TypeScript 3.9์ ์ถ๋ก ํ๋ก์ธ์ค๊ฐ ๊ฐ์ ๋์์ต๋๋ค.
์ ์ค๋ฅ๋ ๋ ์ด์ ๋ฐ์ํ์ง ์์ต๋๋ค.
Promise
์ ๊ด๋ จ๋ ๋ฌธ์ ๋ก ์ธํด ์ด์ ๋ฒ์ ์ TypeScript์์ ๊ณ ์ํ๋ค๋ฉด, 3.9๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
awaited
ํ์
์ ๋ฌด์์
๋๊น? (What About the awaited
Type?)
์ด์ ํธ๋์ปค์ ์ค๊ณ ํ์ ๋
ธํธ๋ฅผ ๋ด์๋ค๋ฉด, awaited
๋ผ๋ ์๋ก์ด ์ฐ์ฐ์์ ๋ํ ์ผ๋ถ ์์
์ ์๊ณ ์์ ๊ฒ์
๋๋ค.
์ด ํ์
์ฐ์ฐ์์ ๋ชฉํ๋ JavaScript์์ Promise
๋ฅผ ํธ๋ ๋ฐฉ์์ ์ ํํ๊ฒ ๋ชจ๋ธ๋ง ํ๋ ๊ฒ์
๋๋ค.
์ฒ์์๋ TypeScript 3.9์์ awaited
์ ์ ๊ณตํ ๊ฒ์ผ๋ก ์์ํ์ง๋ง, ๊ธฐ์กด ์ฝ๋ ๋ฒ ์ด์ค์ ํจ๊ป ์ด๊ธฐ TypeScript ๋น๋๋ฅผ ์คํํจ์ผ๋ก์จ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ์ํํ๊ฒ ๋ฐฐํฌํ๊ธฐ ์ ์ ์ด ๊ธฐ๋ฅ์ ๋ ๋ง์ ์ค๊ณ ์์
์ด ํ์ํ๋ค๋ ์ฌ์ค์ ์์์ต๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก, ๋ ํ์คํด์ง ๋๊น์ง ๋ฉ์ธ ๋ธ๋์น์์ ์ด ๊ธฐ๋ฅ์ ๋นผ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
์ด ๊ธฐ๋ฅ์ ๋ํด ๋ ๋ง์ ์คํ์ ํ ์์ ์ด์ง๋ง, ์ด๋ฒ ๋ฆด๋ฆฌ์ค์์๋ ์ ๊ณตํ์ง ์์ต๋๋ค.
์๋ ํฅ์ (Speed Improvements)
TypeScript 3.9๋ ๋ง์ ์๋ก์ด ์๋ ํฅ์ ๊ธฐ๋ฅ์ด ํฌํจ๋์ด ์์ต๋๋ค. ์ฐ๋ฆฌ ํ์ material-ui ๋ฐ styled-components์ ๊ฐ์ ํจํค์ง๋ฅผ ์ฌ์ฉํ ๋ ํธ์ง / ์ปดํ์ผ ์๋๊ฐ ๋งค์ฐ ์ด์ ํ ๊ฒ์ ํ์ธํ ํ ์ฑ๋ฅ์ ์ค์ ์ ๋์์ต๋๋ค. ๊ฑฐ๋ํ ์ ๋์ธ, ์ธํฐ์น์ , ์กฐ๊ฑด๋ณ ํ์ ๊ทธ๋ฆฌ๊ณ ๋งคํ๋ ํ์ ๊ณผ ๊ด๋ จ๋ ํน์ ๋ณ๋ฆฌํ์ ์ฌ๋ก๋ฅผ ์ต์ ํํ๋ ๋ค์ํ pull request๋ก ์ฌ์ธต ๋ถ์ํ์ต๋๋ค.
- https://github.com/microsoft/TypeScript/pull/36576
- https://github.com/microsoft/TypeScript/pull/36590
- https://github.com/microsoft/TypeScript/pull/36607
- https://github.com/microsoft/TypeScript/pull/36622
- https://github.com/microsoft/TypeScript/pull/36754
- https://github.com/microsoft/TypeScript/pull/36696
์ด๋ฌํ ๊ฐ pull request๋ ํน์ ์ฝ๋ ๋ฒ ์ด์ค์์ ์ปดํ์ผ ์๊ฐ์ด ์ฝ 5-10% ๋จ์ถ๋ฉ๋๋ค. ์ ์ฒด์ ์ผ๋ก material-ui์ ์ปดํ์ผ ์๊ฐ์ด ์ฝ 40% ๋จ์ถ๋์์ต๋๋ค!
๋ํ ์๋ํฐ ์๋๋ฆฌ์ค์์ ํ์ผ ์ด๋ฆ ๋ณ๊ฒฝ ๊ธฐ๋ฅ์ด ์ผ๋ถ ๋ณ๊ฒฝ๋์์ต๋๋ค. ์ฐ๋ฆฌ๋ Visual Studio Code ํ์ผ๋ก๋ถํฐ ํ์ผ ์ด๋ฆ์ ๋ฐ๊ฟ ๋ ์ด๋ค import ๋ฌธ์ ์ ๋ฐ์ดํธํด์ผ ํ๋์ง ํ์ ํ๋๋ฐ 5์ด์์ 10์ด๊ฐ ์์๋ ์ ์๋ค๊ณ ๋ค์์ต๋๋ค. TypeScript 3.9๋ ์ปดํ์ผ๋ฌ ๋ฐ ์ธ์ด ์๋น์ค๊ฐ ํ์ผ ์กฐํ๋ฅผ ์บ์ฑ ํ๋ ๋ฐฉ์์ ๋ด๋ถ ๋ณ๊ฒฝ์ ํตํด ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค.
์ฌ์ ํ ๊ฐ์ ์ ์ฌ์ง๊ฐ ์์ง๋ง, ์ด ์์ ์ด ๋ชจ๋ ์ฌ๋๋ค์๊ฒ ๋ณด๋ค ๋น ๋ฅธ ๊ฒฝํ์ผ๋ก ์ด์ด์ง๊ธฐ๋ฅผ ๋ฐ๋๋๋ค!
// @ts-expect-error
์ฃผ์ (// @ts-expect-error
Comments)
TypeScript๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฑํ๊ณ ํผ๋ธ๋ฆญ API์ ์ผ๋ถ๋ถ์ผ๋ก doStuff
๋ผ๋ ํจ์๋ฅผ export ํ๋ค๊ณ ์์ํด๋ณด์ธ์.
TypeScript ์ฌ์ฉ์๊ฐ ํ์
-์ฒดํฌ ์ค๋ฅ๋ฅผ ๋ฐ์ ์ ์๋๋ก doStuff
ํจ์์ ํ์
์ ๋ ๊ฐ์ string
์ ๊ฐ๋๋ค๊ณ ์ ์ธํ์ง๋ง, ๋ํ JavaScript ์ฌ์ฉ์์๊ฒ ์ ์ฉํ ์ค๋ฅ๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด ๋ฐํ์ ์ค๋ฅ ์ฒดํฌ๋ฅผ ํฉ๋๋ค (๊ฐ๋ฐ ๋น๋ ์์๋ง ๊ฐ๋ฅ).
ts
function doStuff(abc: string, xyz: string) {assert(typeof abc === "string");assert(typeof xyz === "string");// ์ด๋ค ์์ ์ ํ์ธ์}
๊ทธ๋์ TypeScript ์ฌ์ฉ์๋ ํจ์๋ฅผ ์๋ชป ์ฌ์ฉํ ๊ฒฝ์ฐ ์ ์ฉํ ๋นจ๊ฐ ์ค๋ฅ ๋ฐ์ค๊ณผ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋ฐ๊ฒ ๋๋ฉฐ, JavaScript ์ฌ์ฉ์๋ ๋จ์ธ ์ค๋ฅ๋ฅผ ์ป๊ฒ ๋ฉ๋๋ค. ์ด๋ฌํ ์๋์ ํ ์คํธํ๊ธฐ ์ํด์, ์ ๋ ํ ์คํธ๋ฅผ ์์ฑํ๊ฒ ์ต๋๋ค.
ts
expect(() => {doStuff(123, 456);}).toThrow();
๋ถํํ๋ ์์ ํ ์คํธ๊ฐ TypeScript์์ ์์ฑ๋๋ค๋ฉด, TypeScript๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํฌ ๊ฒ์ ๋๋ค!
ts
doStuff(123, 456);// ~~~// ์ค๋ฅ: 'number' ํ์ ์ 'string' ํ์ ์ ํ ๋นํ ์ ์์ต๋๋ค.
๊ทธ๋์ TypeScript 3.9๋ ์๋ก์ด ๊ธฐ๋ฅ์ ๋์
ํ์ต๋๋ค: // @ts-expect-error
์ฃผ์.
๋ผ์ธ ์์ // @ts-expect-error
์ฃผ์์ด ๋ถ์ด ์์ ๊ฒฝ์ฐ, TypeScript๋ ํด๋น ์ค๋ฅ๋ฅผ ๋ณด๊ณ ํ๋ ๊ฒ์ ๋ฉ์ถฅ๋๋ค;
๊ทธ๋ฌ๋ ์ค๋ฅ๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด, TypeScript๋ // @ts-expect-error
๊ฐ ํ์ํ์ง ์๋ค๊ณ ๋ณด๊ณ ํ ๊ฒ์
๋๋ค.
๊ฐ๋จํ ์๋ก, ๋ค์ ์ฝ๋๋ ๊ด์ฐฎ์ต๋๋ค
ts
// @ts-expect-errorconsole.log(47 * "octopus");
๊ทธ๋ฌ๋ ๋ค์ ์ฝ๋๋
ts
// @ts-expect-errorconsole.log(1 + 1);
์ค๋ฅ๋ก ์ด์ด์ง ๊ฒ์ ๋๋ค
Unused '@ts-expect-error' directive.
์ด ๊ธฐ๋ฅ์ ๊ตฌํํ ์ปจํธ๋ฆฌ๋ทฐํฐ, Josh Goldberg์๊ฒ ํฐ ๊ฐ์ฌ๋ฅผ ๋๋ฆฝ๋๋ค.
์์ธํ ๋ด์ฉ์ the ts-expect-error
pull request๋ฅผ ์ฐธ๊ณ ํ์ธ์.
ts-ignore
๋๋ ts-expect-error
? (ts-ignore
or ts-expect-error
?)
์ด๋ค ์ ์์๋ // @ts-expect-error
๊ฐ // @ts-ignore
๊ณผ ์ ์ฌํ๊ฒ ์ต์ ์ฃผ์(suppression comment)์ผ๋ก ์์ฉํ ์ ์์ต๋๋ค.
์ฐจ์ด์ ์ // @ts-ignore
๋ ๋ค์ ํ์ ์ค๋ฅ๊ฐ ์์ ๊ฒฝ์ฐ ์๋ฌด๊ฒ๋ ํ์ง ์๋๋ค๋ ๊ฒ์
๋๋ค.
๊ธฐ์กด // @ts-ignore
์ฃผ์์ // @ts-expect-error
๋ก ๋ฐ๊พธ๊ณ ์ถ์ ๋ง์์ด ๋ค ์ ์์ผ๋ฉฐ, ํฅํ ์ฝ๋์ ๋ฌด์์ด ์ ํฉํ์ง ๊ถ๊ธํ ์ ์์ต๋๋ค.
์ ์ ์ผ๋ก ๋น์ ๊ณผ ๋น์ ํ์ ์ ํ์ด์ง๋ง, ์ฐ๋ฆฌ๋ ์ด๋ค ์ํฉ์์ ์ด๋ค ๊ฒ์ ์ ํํ ๊ฒ์ธ์ง์ ๋ํ ๋ช ๊ฐ์ง ์์ด๋์ด๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
๋ค์ ๊ฒฝ์ฐ๋ผ๋ฉด ts-expect-error
๋ฅผ ์ ํํ์ธ์:
- ํ์ ์์คํ ์ด ์๋์ ๋ํ ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๋ ํ ์คํธ ์ฝ๋ ์์ฑ์ ์ํ๋ ๊ฒฝ์ฐ
- ์์ ์ด ๋นจ๋ฆฌ ์ด๋ฃจ์ด์ง๊ธธ ์ํ๋ฉฐ ๋น ๋ฅธ ํด๊ฒฐ์ฑ ์ด ํ์ํ ๊ฒฝ์ฐ
- ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ฝ๋๊ฐ ๋ค์ ์ ํจํด์ง๋ฉด ๋ฐ๋ก ์ต์ ์ฃผ์์ ์ญ์ ํ๊ธธ ์ํ๋ ํ์ ์ ์ธ ํ์ด ์ด๋๋ ์ ๋นํ-ํฌ๊ธฐ์ ํ๋ก์ ํธ์์ ์์ ํ๋ ๊ฒฝ์ฐ
๋ค์ ๊ฒฝ์ฐ๋ผ๋ฉด ts-ignore
๋ฅผ ์ ํํ์ธ์:
- ๋ ํฐ ํ๋ก์ ํธ๋ฅผ ๊ฐ๊ณ ์๊ณ ์ฝ๋์์ ๋ฐ์ํ ์๋ก์ด ์ค๋ฅ์ ๋ช ํํ ์ฑ ์์๋ฅผ ์ฐพ๊ธฐ ํ๋ ๊ฒฝ์ฐ
- TypeScript์ ๋ ๊ฐ์ง ๋ฒ์ ์ฌ์ด์์ ์ ๊ทธ๋ ์ด๋ํ๋ ์ค์ด๊ณ , ํ ๋ฒ์ ์์๋ ์ฝ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ง ๋๋จธ์ง ๋ฒ์ ์์๋ ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ
- ์์งํ ์ด๋ค ์ต์ ๋ ๋์์ง ๊ฒฐ์ ํ ์๊ฐ์ด ์๋ ๊ฒฝ์ฐ
์กฐ๊ฑด๋ฌธ์์ ํธ์ถ๋์ง ์์ ํจ์ ์ฒดํฌ (Uncalled Function Checks in Conditional Expressions)
TypeScript 3.7์์ ํจ์ ํธ์ถ์ ์์ด๋ฒ๋ ธ์ ๊ฒฝ์ฐ ์ค๋ฅ๋ฅผ ๋ณด๊ณ ํ๊ธฐ ์ํด ํธ์ถ๋์ง ์์ ํจ์ ์ฒดํฌ๋ฅผ ๋์ ํ์ต๋๋ค.
ts
function hasImportantPermissions(): boolean {// ...}// ์ด๋ฐ!if (hasImportantPermissions) {// ~~~~~~~~~~~~~~~~~~~~~~~// hasImportantPermissions ํจ์๊ฐ ํญ์ ์ ์๋์ด ์๊ธฐ ๋๋ฌธ์, ์ด ์กฐ๊ฑด๋ฌธ์ ํญ์ true๋ฅผ ๋ฐํํฉ๋๋ค.// ๋์ ์ด๊ฒ์ ํธ์ถํ๋ ค ํ์ จ๋์?deleteAllTheImportantFiles();}
๊ทธ๋ฌ๋, ์ด ์ค๋ฅ๋ if
๋ฌธ์ ์กฐ๊ฑด์๋ง ์ ์ฉ๋ฉ๋๋ค.
Alexander Tarasyuk์ a pull request ๋๋ถ์, ์ด ๊ธฐ๋ฅ์ ์ผํญ ์กฐ๊ฑด ์ฐ์ฐ์๋ ์ง์ํ๊ฒ ๋์์ต๋๋ค (์. cond ? trueExpr : falseExpr
๊ตฌ๋ฌธ).
ts
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);}}
https://github.com/microsoft/TypeScript/issues/36048
์๋ํฐ ๊ฐ์ (Editor Improvements)
TypeScript ์ปดํ์ผ๋ฌ๋ ์ฃผ์ ์๋ํฐ์ TypeScript ์์ฑ ๊ฒฝํ๋ฟ๋ง ์๋๋ผ, Visual Studio ๊ณ์ด ์๋ํฐ์ JavaScript ์์ฑ ๊ฒฝํ์๋ ์ํฅ์ ์ค๋๋ค. ์๋ํฐ์์ ์๋ก์ด TypeScript/JavaScript ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๊ฒ์ ์๋ํฐ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์ง๋ง
- Visual Studio Code๋ ๋ค๋ฅธ ๋ฒ์ ์ TypeScript ์ ํ์ ์ง์ํฉ๋๋ค. ๋๋, ์ต์ ์ผ๋ก ์ ์งํ๊ธฐ ์ํ JavaScript/TypeScript Nightly Extension๋ ์์ต๋๋ค.(๋์ฒด๋ก ์์ ์ ์ ๋๋ค.)
- Visual Studio 2017/2019 ์๋ [SDK ์ค์น ํ๋ก๊ทธ๋จ] ๊ณผ MSBuild ์ค์น๊ฐ ์์ต๋๋ค.
- Sublime Text 3์ ๋ค๋ฅธ ๋ฒ์ ์ TypeScript ์ ํ์ ์ง์ํฉ๋๋ค.
JavaScript์์ CommonJS ์๋-import (CommonJS Auto-Imports in JavaScript)
CommonJS ๋ชจ๋์ ์ฌ์ฉํ๋ JavaScript ํ์ผ์์ ์๋-import ๊ธฐ๋ฅ์ด ํฌ๊ฒ ๊ฐ์ ๋์์ต๋๋ค.
์ด์ ๋ฒ์ ์์๋, TypeScript๋ ํญ์ ํ์ผ์ ๊ด๊ณ์์ด ECMAScript-์คํ์ผ์ import๋ฅผ ์ํ๋ค๊ณ ๊ฐ์ ํ์ต๋๋ค.
js
import * as fs from "fs";
ํ์ง๋ง, ๋ชจ๋ ์ฌ๋์ด JavaScript ํ์ผ์ ์ธ ๋ ECMAScript-์คํ์ผ์ ๋ชจ๋์ ์ํ๋ ๊ฒ์ ์๋๋๋ค.
๋ง์ ์ฌ์ฉ์๊ฐ ์ฌ์ ํ CommonJS-์คํ์ผ์ require(...)
import๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
js
const fs = require("fs");
์ด์ TypeScript๋ ํ์ผ ์คํ์ผ์ ๊น๋ํ๊ณ ์ผ๊ด๋๊ฒ ์ ์งํ๊ธฐ ์ํด์ ์ฌ์ฉ ์ค์ธ import ์ ํ์ ์๋์ผ๋ก ๊ฒ์ํฉ๋๋ค.
์ด ๋ณ๊ฒฝ์ ๋ํ ์์ธํ ๋ด์ฉ์, ํด๋น pull request๋ฅผ ์ฐธ๊ณ ํ์ธ์.
์ฝ๋ ์์ ๊ฐํ ์ ์ง (Code Actions Preserve Newlines)
TypeScript์ ๋ฆฌํฉํฐ๋ง๊ณผ ๋น ๋ฅธ ์์ ์ ์ข ์ข ๊ฐํ์ ์ ์งํ๋๋ฐ ํฐ ์ญํ ์ ํ์ง๋ ์์์ต๋๋ค. ๊ธฐ๋ณธ์ ์ธ ์๋ก ๋ค์ ์ฝ๋๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
ts
const maxValue = 100;/*์์*/for (let i = 0; i <= maxValue; i++) {// ๋จผ์ ์ ๊ณฑ ๊ฐ์ ๊ตฌํ๋ค.let square = i ** 2;// ์ ๊ณฑ ๊ฐ์ ์ถ๋ ฅํ๋ค.console.log(square);}/*๋*/
์๋ํฐ์์ /*์์*/
์์ /*๋*/
๊น์ง ๋ฒ์๋ฅผ ๊ฐ์กฐํ์ฌ ์๋ก์ด ํจ์๋ก ์ถ์ถํ๋ฉด, ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๊ฐ ๋ฉ๋๋ค.
ts
const maxValue = 100;printSquares();function printSquares() {for (let i = 0; i <= maxValue; i++) {// ๋จผ์ ์ ๊ณฑ ๊ฐ์ ๊ตฌํ๋ค.let square = i ** 2;// ์ ๊ณฑ ๊ฐ์ ์ถ๋ ฅํ๋ค.console.log(square);}}
์ด๊ฑด ์ด์์ ์ด์ง ์์ต๋๋ค - for
๋ฃจํ์์ ๊ฐ๊ฐ์ ๋ฌธ ์ฌ์ด์ ๋น ์ค์ด ์์์ง๋ง ๋ฆฌํฉํฐ๋ง์ด ์์ ๋ฒ๋ ธ์ต๋๋ค!
TypeScript 3.9์ ์ฐ๋ฆฌ๊ฐ ์์ฑํ ๊ฒ์ ๋ณด์กดํ๊ธฐ ์ํด ์กฐ๊ธ ๋ ์์
์ ํฉ๋๋ค.
ts
const maxValue = 100;printSquares();function printSquares() {for (let i = 0; i <= maxValue; i++) {// ๋จผ์ ์ ๊ณฑ ๊ฐ์ ๊ตฌํ๋ค.let square = i ** 2;// ์ ๊ณฑ๊ฐ์ ์ถ๋ ฅํ๋ค.console.log(square);}}
์ด pull request์์ ๊ตฌํ์ ๋ํด ๋ ์์ธํ ๋ณผ ์ ์์ต๋๋ค.
๋๋ฝ๋ ๋ฐํ ๋ฌธ ๋น ๋ฅธ ์์ (Quick Fixes for Missing Return Expressions)
ํนํ ํ์ดํ ํจ์์ ์ค๊ดํธ๋ฅผ ์ถ๊ฐํ ๋, ํจ์์ ๋ง์ง๋ง ๋ฌธ์ ๊ฐ์ ๋ฐํํ๋ ๊ฒ์ ์๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
ts
// ์ด์ let f1 = () => 42// ์ค์ - ๋์ผํ์ง ์์!let f2 = () => { 42 }
์ปค๋ฎค๋ํฐ ๋ฉค๋ฒ์ธ Wenlu Wang์ pull request ๋๋ถ์, TypeScript๋ ๋๋ฝ๋ return
๋ฌธ์ ์ถ๊ฐํ๊ฑฐ๋, ์ค๊ดํธ๋ฅผ ์ ๊ฑฐํ๊ฑฐ๋, ๊ฐ์ฒด ๋ฆฌํฐ๋ด ์ฒ๋ผ ๋ณด์ด๋ ํ์ดํ ํจ์ ๋ชธ์ฒด์ ๊ดํธ๋ฅผ ์ถ๊ฐํ๋ ๋น ๋ฅธ-์์ ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
tsconfig.json
ํ์ผ โ์๋ฃจ์
์คํ์ผโ ์ง์ (Support for โSolution Styleโ tsconfig.json
Files)
์๋ํฐ๋ ํ์ผ์ด ์ด๋ค ์ค์ ํ์ผ์ ์ํ๋์ง ํ์
ํ์ฌ ์ ์ ํ ์ต์
์ ์ ์ฉํ ์ ์๋๋ก ํ๊ณ ํ์ฌ โํ๋ก์ ํธโ์ ์ด๋ค ๋ค๋ฅธ ํ์ผ์ด ํฌํจ๋์ด ์๋์ง ํ์
ํด์ผ ํฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก, TypeScript์ ์ธ์ด ์๋ฒ๊ฐ ์ํฅ์ ์ฃผ๋ ์๋ํฐ๋ ๊ฐ ์์ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ฐ๋ผ ์ฌ๋ผ๊ฐ tsconfig.json
์ ์ฐพ์์ผ๋ก์จ ์ด ์์
์ ์ํํฉ๋๋ค.
์ด ๋ฌธ์ ๊ฐ ๋ค์ ์คํจํ๋ ๊ฒฝ์ฐ ์ค ํ๋๋ tsconfig.json์ด ๋จ์ํ ๋ค๋ฅธ tsconfig.json ํ์ผ์ ์ฐธ์กฐํ๊ธฐ ์ํด ์กด์ฌํ ๋์์ต๋๋ค.
json
// tsconfig.json{"files": [],"references": [{ "path": "./tsconfig.shared.json" },{ "path": "./tsconfig.frontend.json" },{ "path": "./tsconfig.backend.json" },]}
๋ค๋ฅธ ํ๋ก์ ํธ ํ์ผ์ ๊ด๋ฆฌ๋ง ํ๋ ์ด ํ์ผ์ ์ด๋ค ํ๊ฒฝ์์๋ ์ข
์ข
โ์๋ฃจ์
โ์ด๋ผ๊ณ ๋ถ๋ฆฝ๋๋ค.
์ฌ๊ธฐ์ tsconfig.*.json
ํ์ผ ์ค ์ด๋ค ํ์ผ๋ ์๋ฒ์ ์ํด ๊ฒ์๋์ง ์์ง๋ง, ํ์ฌ .ts
ํ์ผ์ด ๋ฃจํธ์ tsconfig.json
์ ์ธ๊ธ๋ ํ๋ก์ ํธ ์ค ํ๋์ ์ํ๋ค๋ ๊ฒ์ ์ธ์ด ์๋ฒ๊ฐ ์ดํดํ๊ธฐ๋ฅผ ์ํฉ๋๋ค.
TypeScript 3.9 ๋ ์ด ์ค์ ์ ๋ํ ์๋๋ฆฌ์ค ์์ ์ ์ง์ํฉ๋๋ค. ๋ ์์ธํ ์ฌํญ์, ์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ pull request๋ฅผ ํ์ธํ์ธ์.
์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ (Breaking Changes)
์ ํ์ ์ฒด์ด๋๊ณผ ๋์ด ์๋ ๋จ์ธ์์ ํ์ฑ ์ฐจ์ด์ (Parsing Differences in Optional Chaining and Non-Null Assertions)
์ต๊ทผ์ TypeScript๋ ์ ํ์ ์ฒด์ด๋ ์ฐ์ฐ์๋ฅผ ๋์
ํ์ง๋ง, ๋์ด ์๋ ๋จ์ธ ์ฐ์ฐ์ (!
)์ ํจ๊ป ์ฌ์ฉํ๋ ์ ํ์ ์ฒด์ด๋ (?.
)์ ๋์์ด ๋งค์ฐ ์ง๊ด์ ์ด์ง ์๋ค๋ ์ฌ์ฉ์ ํผ๋๋ฐฑ์ ๋ฐ์์ต๋๋ค.
๊ตฌ์ฒด์ ์ผ๋ก, ์ด์ ๋ฒ์ ์์๋ ์ฝ๋๊ฐ
ts
foo?.bar!.baz
๋ค์ JavaScript์ ๋์ผํ๊ฒ ํด์๋์์ต๋๋ค.
js
(foo?.bar).baz
์์ ์ฝ๋์์ ๊ดํธ๋ ์ ํ์ ์ฒด์ด๋์ โ๋จ๋ฝโ ๋์์ ์ค๋จํฉ๋๋ค, ๊ทธ๋์ ๋ง์ฝ foo
๊ฐ undefined
์ด๋ฉด, baz
์ ์ ๊ทผํ๋ ๊ฒ์ ๋ฐํ์ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค.
์ด ๋์์ ์ง์ ํ ๋ฐ๋ฒจํ๊ณผ ํผ๋๋ฐฑ์ ์ค ๋๋ถ๋ถ์ ์ฌ์ฉ์๋ค์ ์ด ๋์์ด ์๋ชป๋์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ ํฌ๋ ๊ทธ๋ ๊ฒ ์๊ฐํฉ๋๋ค!
bar
์ ํ์
์์ null
๊ณผ undefined
๋ฅผ ์ ๊ฑฐํ๋ ๊ฒ์ด ์๋์ด๊ธฐ ๋๋ฌธ์ ๊ฐ์ฅ ๋ง์ด ๋ค์ ๋ง์ !
์ฐ์ฐ์๋ ๊ทธ๋ฅ โ์ฌ๋ผ์ ธ์ผ ํ๋คโ์
๋๋ค.
์ฆ, ๋๋ถ๋ถ์ ์ฌ๋๋ค์ ์๋ณธ ๋ฌธ์ฅ์ด ๋ค์๊ณผ ๊ฐ์ด
js
foo?.bar.baz
foo
๊ฐ undefined
์ผ ๋, ๊ทธ๋ฅ undefined
๋ก ํ๊ฐํ๋ ๊ฒ์ผ๋ก ํด์๋์ด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค
์ด๊ฒ์ด ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ด์ง๋ง, ๋๋ถ๋ถ์ ์ฝ๋๊ฐ ์๋ก์ด ํด์์ ์ผ๋์ ๋๊ณ ์์ฑ๋์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ด์ ๋์์ผ๋ก ๋๋๋ฆฌ๊ณ ์ถ์ ์ฌ์ฉ์๋ !
์ฐ์ฐ์ ์ผ์ชฝ์ ๋ช
์์ ์ธ ๊ดํธ๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.
ts
(foo?.bar)!.baz
}
์ >
๋ ์ด์ ์ ํจํ์ง ์์ JSX ํ
์คํธ ๋ฌธ์์
๋๋ค (}
and >
are Now Invalid JSX Text Characters)
JSX ๋ช
์ธ์์๋ ํ
์คํธ ์์น์ }
์ >
๋ฌธ์์ ์ฌ์ฉ์ ๊ธ์งํฉ๋๋ค.
TypeScript์ ๋ฐ๋ฒจ์ ์ด ๊ท์น์ ๋ ์ ํฉํ๊ฒ ์ ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
์ด ๋ฌธ์๋ฅผ ๋ฃ๊ธฐ ์ํ ์๋ก์ด ๋ฐฉ๋ฒ์ HTML ์ด์ค์ผ์ดํ ์ฝ๋๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ (์๋ฅผ ๋ค์ด, <span> 2 > 1 </div>
) ๋ฌธ์์ด ๋ฆฌํฐ๋ด๋ก ํํ์์ ๋ฃ๋ ๊ฒ์
๋๋ค (์๋ฅผ ๋ค์ด, <span> 2 {">"} 1 </div
).
๋คํํ, Brad Zacher์ pull request ๋๋ถ์, ๋ค์ ๋ฌธ์ฅ๊ณผ ํจ๊ป ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋ฐ์ ์ ์์ต๋๋ค
Unexpected token. Did you mean `{'>'}` or `>`?Unexpected token. Did you mean `{'}'}` or `}`?
์๋ฅผ ๋ค์ด:
tsx
let directions = <span>Navigate to: Menu Bar > Tools > Options</div>// ~ ~// Unexpected token. Did you mean `{'>'}` or `>`?
์ด ์ค๋ฅ ๋ฉ์์ง๋ ํธ๋ฆฌํ๊ณ ๋น ๋ฅธ ์์ ๊ณผ ํจ๊ป ์ ๊ณต๋๊ณ Alexander Tarasyuk ๋๋ถ์, ๋ง์ ์ค๋ฅ๊ฐ ์์ผ๋ฉด ์ด ๋ณ๊ฒฝ์ฌํญ์ ์ผ๊ด ์ ์ฉ ํ ์ ์์ต๋๋ค.
๊ต์งํฉ๊ณผ ์ ํ์ ํ๋กํผํฐ์ ๋ํ ๋ ์๊ฒฉํด์ง ๊ฒ์ฌ (Stricter Checks on Intersections and Optional Properties)
์ผ๋ฐ์ ์ผ๋ก, A & B
์ ๊ฐ์ ๊ต์ฐจ ํ์
์ A
๋๋ B
๊ฐ C
์ ํ ๋นํ ์ ์์ผ๋ฉด, A & B
๋ C
์ ํ ๋นํ ์ ์์ต๋๋ค; ํ์ง๋ง, ๊ฐ๋ ์ ํ์ ํ๋กํผํฐ์์ ๋ฌธ์ ๊ฐ ์๊น๋๋ค.
์๋ฅผ ๋ค์ด, ๋ค์์ ๋ด
์๋ค:
ts
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;
์ด์ ๋ฒ์ ์ TypeScript์์๋, A
๊ฐ C
์ ์์ ํ ํธํ๋์ง ์์ง๋ง, B
๊ฐ C
์ ํธํ ๋์๊ธฐ ๋๋ฌธ์ ํ์ฉ๋์์ต๋๋ค.
TypeScript 3.9์์๋, ๊ต์งํฉ ์์ ๋ชจ๋ ํ์
์ด ๊ตฌ์ ์ ์ธ ๊ฐ์ฒด ํ์
์ด๋ฉด, ํ์
์์คํ
์ ๋ชจ๋ ํ๋กํผํฐ๋ฅผ ํ ๋ฒ์ ๊ณ ๋ คํฉ๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก, TypeScript๋ A & B
์ a
ํ๋กํผํฐ๋ C
์ a
ํ๋กํผํฐ์ ํธํ๋์ง ์๋๋ค๊ณ ๋ด
๋๋ค:
'A & B' ํ์ ์ 'C' ํ์ ์ ํ ๋นํ ์ ์์ต๋๋ค.'a' ํ๋กํผํฐ์ ํ์ ์ ํธํ๋์ง ์์ต๋๋ค.'number' ํ์ ์ 'boolean | undefined' ํ์ ์ ํ ๋นํ ์ ์์ต๋๋ค.
์ด ๋ณ๊ฒฝ์ฌํญ์ ๋ํ ์์ธํ ์ ๋ณด๋, ํด๋น pull request๋ฅผ ์ฐธ์กฐํ์ธ์.
ํ๋ณ ํ๋กํผํฐ๋ก ์ค์ด๋ ๊ต์งํฉ (Intersections Reduced By Discriminant Properties)
์กด์ฌํ์ง ์๋ ๊ฐ์ ๊ธฐ์ ํ๋ ํ์ ์ผ๋ก ๋๋ ์ ์๋ ๋ช ๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด
ts
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);
์ด ์ฝ๋๋ Circle
๊ณผ Square
์ ๊ต์งํฉ์ ์์ฑํ ๋ฐฉ๋ฒ์ด ์ ํ ์๊ธฐ ๋๋ฌธ์ ์ฝ๊ฐ ์ด์ํฉ๋๋ค - ํธํ๋์ง ์๋ ๋ kind
ํ๋๊ฐ ์์ต๋๋ค.
์ด์ ๋ฒ์ ์ TypeScript์์๋, ์ด ์ฝ๋๋ ํ์ฉ๋์๊ณ "circle" & "square"
๊ฐ ์ ๋(never)
์กด์ฌํ ์ ์๋ ๊ฐ์ ์งํฉ์ ๊ธฐ์ ํ๊ธฐ ๋๋ฌธ์ kind
์์ฒด์ ํ์
์ never
์์ต๋๋ค.
TypeScript 3.9์์๋, ํ์
์์คํ
์ด ๋ ๊ณต๊ฒฉ์ ์
๋๋ค - kind
ํ๋กํผํฐ ๋๋ฌธ์ Circle
๊ณผ Square
๋ฅผ ๊ต์ฐจํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค.
๊ทธ๋์ z.kind
๋ฅผ never
๋ก ์ถ์ํ๋ ๋์ , z
์์ฒด(Circle & Square
) ํ์
์ never
๋ก ์ถ์ํฉ๋๋ค.
์ฆ ์์ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ ์ค๋ฅ๋ฅผ ๋ฐ์ํฉ๋๋ค:
'kind' ํ๋กํผํฐ๋ 'never' ํ์ ์ ์กด์ฌํ์ง ์์ต๋๋ค.
๊ด์ฐฐํ ๋๋ถ๋ถ์ ์ค๋ฅ๋ ์๋ชป๋ ํ์ ์ ์ธ๊ณผ ์ผ์นํ๋ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค. ์์ธํ ๋ด์ฉ์ ์๋ฌธ pull request๋ฅผ ๋ณด์ธ์.
Getters/Setters๋ ๋ ์ด์ ์ด๊ฑฐํ์ง ์์ต๋๋ค (Getters/Setters are No Longer Enumerable)
์ด์ ๋ฒ์ ์ TypeScript์์, ํด๋์ค์ get
๊ณผ set
์ ๊ทผ์๋ ์ด๊ฑฐ ๊ฐ๋ฅํ ๋ฐฉ๋ฒ์ผ๋ก ๋ฐฉ์ถ๋์์ต๋๋ค; ํ์ง๋ง, get
๊ณผ set
์ ์ด๊ฑฐํ ์ ์๋ค๋ ECMAScript ์ฌ์์ ๋ฐ๋ฅด์ง ์์์ต๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก, ES5์ ES2015๋ฅผ ํ๊ฒํ
ํ๋ TypeScript ์ฝ๋๋ ๋์์ด ๋ค๋ฅผ ์ ์์ต๋๋ค.
๊นํ๋ธ ์ฌ์ฉ์ pathurs์ pull request ๋๋ถ์, TypeScript 3.9๋ ์ด์ ๊ด๋ จํ์ฌ ECMAScript์ ๋ ๋ฐ์ ํ๊ฒ ํธํ๋ฉ๋๋ค.
any
๋ก ํ์ฅ๋ ํ์
๋งค๊ฐ๋ณ์๋ ๋ ์ด์ any
์ฒ๋ผ ํ๋ํ์ง ์์ (Type Parameters That Extend any
No Longer Act as any
)
์ด์ ๋ฒ์ ์ TypeScript์์ any
๋ก ์ ํ๋ ํ์
๋งค๊ฐ๋ณ์๋ any
๋ก ๋ค๋ฃฐ ์ ์์์ต๋๋ค.
ts
function foo<T extends any>(arg: T) {arg.spfjgerijghoied; // ์ค๋ฅ๊ฐ ์๋!}
์ด๋ ์ค์์์ต๋๋ค, ๊ทธ๋์ TypeScript 3.9์์๋ ๋ ๋ณด์์ ์ธ ์ ๊ทผ์ ์ทจํ๊ณ ์ด๋ฐ ์์ฌ์ค๋ฌ์ด ์์ ์ ๋ํด ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค.
ts
function foo<T extends any>(arg: T) {arg.spfjgerijghoied;// ~~~~~~~~~~~~~~~// 'spfjgerijghoied' ํ๋กํผํฐ๋ 'T' ํ์ ์ ์กด์ฌํ์ง ์์ต๋๋ค.}
export *
์ ํญ์ ์ ์ง๋ฉ๋๋ค (export *
is Always Retained)
์ด์ TypeScript ๋ฒ์ ์์ export * from "foo"
๊ฐ์ ์ ์ธ์ foo
๊ฐ ์ด๋ ํ ๊ฐ๋ export ํ์ง ์์ผ๋ฉด JavaScript ์ถ๋ ฅ์์ ์ ์ธ๋์์ต๋๋ค.
์ด๋ฐ ๋ด๋ณด๋ด๊ธฐ๋ ํ์
-์งํฅ์ ์ด๊ณ ๋ฐ๋ฒจ์์ ์๋ฎฌ๋ ์ดํธ ๋ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค.
TypeScrip 3.9๋ ์ด๋ฐ export *
์ ์ธ์ ํญ์ ๋ด๋ณด๋
๋๋ค.
์ค์ ๋ก ์ด ๋ณํ๊ฐ ๊ธฐ์กด ์ฝ๋๋ฅผ ๊นจ๋จ๋ฆด ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ง ์์ต๋๋ค.
๋ ๋ง์ libdom.d.ts ๊ฐ์ (More libdom.d.ts refinements)
Web IDL ํ์ผ์์ ๋ฐ๋ก TypeScript์ ๋ด์ฅ .d.ts. ๋ผ์ด๋ธ๋ฌ๋ฆฌ (lib.d.ts ๋ฐ ์ ํ๊ตฐ)๊ฐ ์์ฑ๋ ์ ์๋๋ก DOM ๊ท๊ฒฉ์ TypeScript์ ๋ด์ฅ .d.ts. ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฎ๊ธฐ๋ ์์ ์ ๊ณ์ ์งํํ๊ณ ์์ต๋๋ค. ๊ทธ ๊ฒฐ๊ณผ ๋ฏธ๋์ด ์ก์ธ์ค์ ๊ด๋ จ๋ ์ผ๋ถ ๋ฒค๋๋ณ ํ์ ์ด ์ ๊ฑฐ๋์์ต๋๋ค.
ํ๋ก์ ํธ์ ambient *.d.ts ํ์ผ์ ์ด ํ์ผ์ ์ถ๊ฐํ๋ฉด ๋ค์ ๋ณต๊ตฌํ ์ ์์ต๋๋ค:
ts
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;}