Skip to content

Latest commit

ย 

History

History
535 lines (387 loc) ยท 25.6 KB

typescript-3.9.md

File metadata and controls

535 lines (387 loc) ยท 25.6 KB

์ถ”๋ก ๊ณผ Promise.all ๊ฐœ์„  (Improvements in Inference and Promise.all)

์ตœ์‹  ๋ฒ„์ „์˜ TypeScript(์•ฝ 3.7)๋Š” Promise.all ๋ฐ Promise.race์™€ ๊ฐ™์€ ํ•จ์ˆ˜ ์„ ์–ธ์ด ์—…๋ฐ์ดํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์•ˆํƒ€๊น๊ฒŒ๋„, ํŠนํžˆ null ๋˜๋Š” undefined์™€ ๊ฐ’์„ ํ˜ผํ•ฉํ•  ๋•Œ, ์•ฝ๊ฐ„์˜ ํšŒ๊ท€๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

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๋กœ ์‹ฌ์ธต ๋ถ„์„ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ฐ 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 ์‚ฌ์šฉ์ž์—๊ฒŒ ์œ ์šฉํ•œ ์˜ค๋ฅ˜๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜ ์ฒดํฌ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค (๊ฐœ๋ฐœ ๋นŒ๋“œ ์‹œ์—๋งŒ ๊ฐ€๋Šฅ).

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

    // ์–ด๋–ค ์ž‘์—…์„ ํ•˜์„ธ์š”
}

๊ทธ๋ž˜์„œ TypeScript ์‚ฌ์šฉ์ž๋Š” ํ•จ์ˆ˜๋ฅผ ์ž˜๋ชป ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์œ ์šฉํ•œ ๋นจ๊ฐ„ ์˜ค๋ฅ˜ ๋ฐ‘์ค„๊ณผ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›๊ฒŒ ๋˜๋ฉฐ, JavaScript ์‚ฌ์šฉ์ž๋Š” ๋‹จ์–ธ ์˜ค๋ฅ˜๋ฅผ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ž‘๋™์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด์„œ, ์œ ๋‹› ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

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

๋ถˆํ–‰ํžˆ๋„ ์œ„์˜ ํ…Œ์ŠคํŠธ๊ฐ€ TypeScript์—์„œ ์ž‘์„ฑ๋œ๋‹ค๋ฉด, TypeScript๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

    doStuff(123, 456);
//          ~~~
// ์˜ค๋ฅ˜: 'number' ํƒ€์ž…์€ 'string' ํƒ€์ž…์— ํ• ๋‹นํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ TypeScript 3.9๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค: // @ts-expect-error ์ฃผ์„. ๋ผ์ธ ์•ž์— // @ts-expect-error ์ฃผ์„์ด ๋ถ™์–ด ์žˆ์„ ๊ฒฝ์šฐ, TypeScript๋Š” ํ•ด๋‹น ์˜ค๋ฅ˜๋ฅผ ๋ณด๊ณ ํ•˜๋Š” ๊ฒƒ์„ ๋ฉˆ์ถฅ๋‹ˆ๋‹ค; ๊ทธ๋Ÿฌ๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด, TypeScript๋Š” // @ts-expect-error๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๊ณ  ๋ณด๊ณ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐ„๋‹จํ•œ ์˜ˆ๋กœ, ๋‹ค์Œ ์ฝ”๋“œ๋Š” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค

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

๊ทธ๋Ÿฌ๋‚˜ ๋‹ค์Œ ์ฝ”๋“œ๋Š”

// @ts-expect-error
console.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์—์„œ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ์žŠ์–ด๋ฒ„๋ ธ์„ ๊ฒฝ์šฐ ์˜ค๋ฅ˜๋ฅผ ๋ณด๊ณ ํ•˜๊ธฐ ์œ„ํ•ด ํ˜ธ์ถœ๋˜์ง€ ์•Š์€ ํ•จ์ˆ˜ ์ฒดํฌ๋ฅผ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.

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

// ์ด๋Ÿฐ!
if (hasImportantPermissions) {
//  ~~~~~~~~~~~~~~~~~~~~~~~
// hasImportantPermissions ํ•จ์ˆ˜๊ฐ€ ํ•ญ์ƒ ์ •์˜๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ด ์กฐ๊ฑด๋ฌธ์€ ํ•ญ์ƒ true๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
// ๋Œ€์‹  ์ด๊ฒƒ์„ ํ˜ธ์ถœํ•˜๋ ค ํ•˜์…จ๋‚˜์š”?
    deleteAllTheImportantFiles();
}

๊ทธ๋Ÿฌ๋‚˜, ์ด ์˜ค๋ฅ˜๋Š” if ๋ฌธ์˜ ์กฐ๊ฑด์—๋งŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. Alexander Tarasyuk์˜ a pull request ๋•๋ถ„์—, ์ด ๊ธฐ๋Šฅ์€ ์‚ผํ•ญ ์กฐ๊ฑด ์—ฐ์‚ฐ์ž๋„ ์ง€์›ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค (์˜ˆ. cond ? trueExpr : falseExpr ๊ตฌ๋ฌธ).

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)

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๋ฅผ ์›ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

import * as fs from "fs";

ํ•˜์ง€๋งŒ, ๋ชจ๋“  ์‚ฌ๋žŒ์ด JavaScript ํŒŒ์ผ์„ ์“ธ ๋•Œ ECMAScript-์Šคํƒ€์ผ์˜ ๋ชจ๋“ˆ์„ ์›ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋งŽ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์—ฌ์ „ํžˆ CommonJS-์Šคํƒ€์ผ์˜ require(...) import๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

const fs = require("fs");

์ด์ œ TypeScript๋Š” ํŒŒ์ผ ์Šคํƒ€์ผ์„ ๊น”๋”ํ•˜๊ณ  ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ ์ค‘์ธ import ์œ ํ˜•์„ ์ž๋™์œผ๋กœ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€, ํ•ด๋‹น pull request๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

์ฝ”๋“œ ์ž‘์—… ๊ฐœํ–‰ ์œ ์ง€ (Code Actions Preserve Newlines)

TypeScript์˜ ๋ฆฌํŒฉํ„ฐ๋ง๊ณผ ๋น ๋ฅธ ์ˆ˜์ •์€ ์ข…์ข… ๊ฐœํ–‰์„ ์œ ์ง€ํ•˜๋Š”๋ฐ ํฐ ์—ญํ• ์„ ํ•˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์ธ ์˜ˆ๋กœ ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

const maxValue = 100;

/*์‹œ์ž‘*/
for (let i = 0; i <= maxValue; i++) {
    // ๋จผ์ € ์ œ๊ณฑ ๊ฐ’์„ ๊ตฌํ•œ๋‹ค.
    let square = i ** 2;

    // ์ œ๊ณฑ ๊ฐ’์„ ์ถœ๋ ฅํ•œ๋‹ค.
    console.log(square);
}
/*๋*/

์—๋””ํ„ฐ์—์„œ /*์‹œ์ž‘*/ ์—์„œ /*๋*/ ๊นŒ์ง€ ๋ฒ”์œ„๋ฅผ ๊ฐ•์กฐํ•˜์—ฌ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋กœ ์ถ”์ถœํ•˜๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

const maxValue = 100;

printSquares();

function printSquares() {
    for (let i = 0; i <= maxValue; i++) {
        // ๋จผ์ € ์ œ๊ณฑ ๊ฐ’์„ ๊ตฌํ•œ๋‹ค.
        let square = i ** 2;
        // ์ œ๊ณฑ ๊ฐ’์„ ์ถœ๋ ฅํ•œ๋‹ค.
        console.log(square);
    }
}

์ด์ „ ๋ฒ„์ „์˜ TypeScript์—์„  ํ•จ์ˆ˜๋กœ ๋ฃจํ”„ ์ถ”์ถœ์€. ๊ฐœํ–‰์„ ์œ ์ง€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๊ฑด ์ด์ƒ์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค - for ๋ฃจํ”„์—์„œ ๊ฐ๊ฐ์˜ ๋ฌธ ์‚ฌ์ด์— ๋นˆ ์ค„์ด ์žˆ์—ˆ์ง€๋งŒ ๋ฆฌํŒฉํ„ฐ๋ง์ด ์—†์• ๋ฒ„๋ ธ์Šต๋‹ˆ๋‹ค! TypeScript 3.9์€ ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ ๊ฒƒ์„ ๋ณด์กดํ•˜๊ธฐ ์œ„ํ•ด ์กฐ๊ธˆ ๋” ์ž‘์—…์„ ํ•ฉ๋‹ˆ๋‹ค.

const maxValue = 100;

printSquares();

function printSquares() {
    for (let i = 0; i <= maxValue; i++) {
        // ๋จผ์ € ์ œ๊ณฑ ๊ฐ’์„ ๊ตฌํ•œ๋‹ค.
        let square = i ** 2;

        // ์ œ๊ณฑ๊ฐ’์„ ์ถœ๋ ฅํ•œ๋‹ค.
        console.log(square);
    }
}

TypeScript 3.9์˜ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ๋ฃจํ”„ ์ถ”์ถœ. ๊ฐœํ–‰์ด ๋ณด์กด๋จ

์ด pull request์—์„œ ๊ตฌํ˜„์— ๋Œ€ํ•ด ๋” ์ž์„ธํžˆ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๋ฝ๋œ ๋ฐ˜ํ™˜ ๋ฌธ ๋น ๋ฅธ ์ˆ˜์ • (Quick Fixes for Missing Return Expressions)

ํŠนํžˆ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์— ์ค‘๊ด„ํ˜ธ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ, ํ•จ์ˆ˜์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ์žŠ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

// ์ด์ „
let f1 = () => 42

// ์‹ค์ˆ˜ - ๋™์ผํ•˜์ง€ ์•Š์Œ!
let f2 = () => { 42 }

์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฉค๋ฒ„์ธ Wenlu Wang์˜ pull request ๋•๋ถ„์—, TypeScript๋Š” ๋ˆ„๋ฝ๋œ return ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ์ค‘๊ด„ํ˜ธ๋ฅผ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜, ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋ชธ์ฒด์— ๊ด„ํ˜ธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋น ๋ฅธ-์ˆ˜์ •์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

TypeScript๋Š” return ๋ฌธ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ค‘๊ด„ํ˜ธ๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ ์‹์ด ๋ฐ˜ํ™˜๋˜์ง€ ์•Š๋Š” ์˜ค๋ฅ˜๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

tsconfig.json ํŒŒ์ผ "์†”๋ฃจ์…˜ ์Šคํƒ€์ผ" ์ง€์› (Support for "Solution Style" tsconfig.json Files)

์—๋””ํ„ฐ๋Š” ํŒŒ์ผ์ด ์–ด๋–ค ์„ค์ • ํŒŒ์ผ์— ์†ํ•˜๋Š”์ง€ ํŒŒ์•…ํ•˜์—ฌ ์ ์ ˆํ•œ ์˜ต์…˜์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ  ํ˜„์žฌ "ํ”„๋กœ์ ํŠธ"์— ์–ด๋–ค ๋‹ค๋ฅธ ํŒŒ์ผ์ด ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ํŒŒ์•…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ, TypeScript์˜ ์–ธ์–ด ์„œ๋ฒ„๊ฐ€ ์˜ํ–ฅ์„ ์ฃผ๋Š” ์—๋””ํ„ฐ๋Š” ๊ฐ ์ƒ์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๋”ฐ๋ผ ์˜ฌ๋ผ๊ฐ€ tsconfig.json์„ ์ฐพ์Œ์œผ๋กœ์จ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๊ฐ€ ๋‹ค์†Œ ์‹คํŒจํ•˜๋Š” ๊ฒฝ์šฐ ์ค‘ ํ•˜๋‚˜๋Š” tsconfig.json์ด ๋‹จ์ˆœํžˆ ๋‹ค๋ฅธ tsconfig.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๋Š” ์„ ํƒ์  ์ฒด์ด๋‹ ์—ฐ์‚ฐ์ž๋ฅผ ๋„์ž…ํ–ˆ์ง€๋งŒ, ๋„์ด ์•„๋‹Œ ๋‹จ์–ธ ์—ฐ์‚ฐ์ž (!)์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ์„ ํƒ์  ์ฒด์ด๋‹ (?.)์˜ ๋™์ž‘์ด ๋งค์šฐ ์ง๊ด€์ ์ด์ง€ ์•Š๋‹ค๋Š” ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.

๊ตฌ์ฒด์ ์œผ๋กœ, ์ด์ „ ๋ฒ„์ „์—์„œ๋Š” ์ฝ”๋“œ๊ฐ€

foo?.bar!.baz

๋‹ค์Œ JavaScript์™€ ๋™์ผํ•˜๊ฒŒ ํ•ด์„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

(foo?.bar).baz

์œ„์— ์ฝ”๋“œ์—์„œ ๊ด„ํ˜ธ๋Š” ์„ ํƒ์  ์ฒด์ด๋‹์˜ "๋‹จ๋ฝ" ๋™์ž‘์„ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค, ๊ทธ๋ž˜์„œ ๋งŒ์•ฝ foo๊ฐ€ undefined์ด๋ฉด, baz์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์€ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

์ด ๋™์ž‘์„ ์ง€์ ํ•œ ๋ฐ”๋ฒจํŒ€๊ณผ ํ”ผ๋“œ๋ฐฑ์„ ์ค€ ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๋“ค์€ ์ด ๋™์ž‘์ด ์ž˜๋ชป๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ €ํฌ๋„ ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค! bar์˜ ํƒ€์ž…์—์„œ null๊ณผ undefined๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ์˜๋„์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€์žฅ ๋งŽ์ด ๋“ค์€ ๋ง์€ ! ์—ฐ์‚ฐ์ž๋Š” ๊ทธ๋ƒฅ "์‚ฌ๋ผ์ ธ์•ผ ํ•œ๋‹ค"์ž…๋‹ˆ๋‹ค.

์ฆ‰, ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์€ ์›๋ณธ ๋ฌธ์žฅ์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด

foo?.bar.baz

foo๊ฐ€ undefined์ผ ๋•Œ, ๊ทธ๋ƒฅ undefined๋กœ ํ‰๊ฐ€ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํ•ด์„๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค

์ด๊ฒƒ์ด ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ์ฝ”๋“œ๊ฐ€ ์ƒˆ๋กœ์šด ํ•ด์„์„ ์—ผ๋‘์— ๋‘๊ณ  ์ž‘์„ฑ๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ๋™์ž‘์œผ๋กœ ๋˜๋Œ๋ฆฌ๊ณ  ์‹ถ์€ ์‚ฌ์šฉ์ž๋Š” ! ์—ฐ์‚ฐ์ž ์™ผ์ชฝ์— ๋ช…์‹œ์ ์ธ ๊ด„ํ˜ธ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(foo?.bar)!.baz

} ์™€ > ๋Š” ์ด์ œ ์œ ํšจํ•˜์ง€ ์•Š์€ JSX ํ…์ŠคํŠธ ๋ฌธ์ž์ž…๋‹ˆ๋‹ค (} and > are Now Invalid JSX Text Characters)

JSX ๋ช…์„ธ์„œ์—๋Š” ํ…์ŠคํŠธ ์œ„์น˜์— }์™€ > ๋ฌธ์ž์˜ ์‚ฌ์šฉ์„ ๊ธˆ์ง€ํ•ฉ๋‹ˆ๋‹ค. TypeScript์™€ ๋ฐ”๋ฒจ์€ ์ด ๊ทœ์น™์„ ๋” ์ ํ•ฉํ•˜๊ฒŒ ์ ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ž๋ฅผ ๋„ฃ๊ธฐ ์œ„ํ•œ ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•์€ HTML ์ด์Šค์ผ€์ดํ”„ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ (์˜ˆ๋ฅผ ๋“ค์–ด, <span> 2 &gt 1 </div>) ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด๋กœ ํ‘œํ˜„์‹์„ ๋„ฃ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค (์˜ˆ๋ฅผ ๋“ค์–ด, <span> 2 {">"} 1 </div).

๋‹คํ–‰ํžˆ, Brad Zacher์˜ pull request ๋•๋ถ„์—, ๋‹ค์Œ ๋ฌธ์žฅ๊ณผ ํ•จ๊ป˜ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

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

์˜ˆ๋ฅผ ๋“ค์–ด:

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

์ด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋Š” ํŽธ๋ฆฌํ•˜๊ณ  ๋น ๋ฅธ ์ˆ˜์ •๊ณผ ํ•จ๊ป˜ ์ œ๊ณต๋˜๊ณ  Alexander Tarasyuk ๋•๋ถ„์—, ๋งŽ์€ ์˜ค๋ฅ˜๊ฐ€ ์žˆ์œผ๋ฉด ์ด ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ผ๊ด„ ์ ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ต์ง‘ํ•ฉ๊ณผ ์„ ํƒ์  ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•œ ๋” ์—„๊ฒฉํ•ด์ง„ ๊ฒ€์‚ฌ (Stricter Checks on Intersections and Optional Properties)

์ผ๋ฐ˜์ ์œผ๋กœ, A & B์™€ ๊ฐ™์€ ๊ต์ฐจ ํƒ€์ž…์€ A ๋˜๋Š” B๊ฐ€ C์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์œผ๋ฉด, A & B๋Š” C์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค; ํ•˜์ง€๋งŒ, ๊ฐ€๋” ์„ ํƒ์  ํ”„๋กœํผํ‹ฐ์—์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ์„ ๋ด…์‹œ๋‹ค:

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)

์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฐ’์„ ๊ธฐ์ˆ ํ•˜๋Š” ํƒ€์ž…์œผ๋กœ ๋๋‚  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด

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๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

function foo<T extends any>(arg: T) {
    arg.spfjgerijghoied; // ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹˜!
}

์ด๋Š” ์‹ค์ˆ˜์˜€์Šต๋‹ˆ๋‹ค, ๊ทธ๋ž˜์„œ TypeScript 3.9์—์„œ๋Š” ๋” ๋ณด์ˆ˜์ ์ธ ์ ‘๊ทผ์„ ์ทจํ•˜๊ณ  ์ด๋Ÿฐ ์˜์‹ฌ์Šค๋Ÿฌ์šด ์ž‘์—…์— ๋Œ€ํ•ด ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

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 ํŒŒ์ผ์— ์ด ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋‹ค์‹œ ๋ณต๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

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;
}