Skip to content

Latest commit

ย 

History

History
821 lines (644 loc) ยท 24.9 KB

type-checking-javaScript-files.md

File metadata and controls

821 lines (644 loc) ยท 24.9 KB

TypeScript 2.3 ์ด์ƒ์˜ ๋ฒ„์ „์—์„œ๋Š” --checkJs๋ฅผ ์‚ฌ์šฉํ•ดย .js ํŒŒ์ผ์—์„œ ํƒ€์ž… ๊ฒ€์‚ฌ ๋ฐ ์˜ค๋ฅ˜ ๋ณด๊ณ ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

// @ts-nocheck ์ฃผ์„์„ ๋‹ฌ์•„ ์ผ๋ถ€ ํŒŒ์ผ์—์„œ ํƒ€์ž… ๊ฒ€์‚ฌ๋ฅผ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ์œผ๋ฉฐ; ๋ฐ˜๋Œ€๋กœ // @ts-check ์ฃผ์„์„ ๋‹ฌ์•„ --checkJs๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ผ๋ถ€ .js ํŒŒ์ผ์— ๋Œ€ํ•ด์„œ๋งŒ ํƒ€์ž… ๊ฒ€์‚ฌ๋ฅผ ํ•˜๋„๋ก ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ํŠน์ • ๋ถ€๋ถ„์˜ ์•ž ์ค„์— // @ts-ignore๋ฅผ ๋‹ฌ์•„ ์—๋Ÿฌ๋ฅผ ๋ฌด์‹œํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. tsconfig.json์ด ์žˆ๋Š” ๊ฒฝ์šฐ, JavaScript ๊ฒ€์‚ฌ๋Š” noImplicitAny, strictNullChecks ๋“ฑ์˜ ์—„๊ฒฉํ•œ ํ”Œ๋ž˜๊ทธ๋ฅผ ์šฐ์„ ์‹œํ•œ๋‹ค๋Š” ์ ์„ ์•Œ์•„๋‘์„ธ์š”. ํ•˜์ง€๋งŒ, JavaScript ๊ฒ€์‚ฌ์˜ ์ƒ๋Œ€์ ์ธ ๋Š์Šจํ•จ ๋•๋ถ„์— ์—„๊ฒฉํ•œ ํ”Œ๋ž˜๊ทธ์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋†€๋ผ์šด ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

.ts ํŒŒ์ผ๊ณผ .js ํŒŒ์ผ์€ ํƒ€์ž…์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋ช‡ ๊ฐ€์ง€ ์ฃผ๋ชฉํ• ๋งŒํ•œ ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค:

ํƒ€์ž… ์ •๋ณด๋กœ ์‚ฌ์šฉ๋˜๋Š” JSDoc ํƒ€์ž… (JSDoc types are used for type information)

.js ํŒŒ์ผ์—์„œ๋Š”, ํ”ํžˆ .ts ํŒŒ์ผ์ฒ˜๋Ÿผ ํƒ€์ž…์„ ์ถ”๋ก ํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํƒ€์ž…์„ ์ถ”๋ก ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ, .ts์˜ ํƒ€์ž… ํ‘œ์‹œ์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ JSDoc์„ ์‚ฌ์šฉํ•ด ์ด๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. TypeScript์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, --noImplicitAny๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํƒ€์ž…์„ ์œ ์ถ”ํ•  ์ˆ˜ ์—†๋Š” ๋ถ€๋ถ„์—์„œ ์˜ค๋ฅ˜๋ฅผ ๋ณด๊ณ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. (ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์„ ์ œ์™ธํ•˜๊ณ ; ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.)

์„ ์–ธ์— JSDoc ํ‘œ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ์„ ์–ธ์˜ ํƒ€์ž…์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด:

/** @type {number} */
var x;

x = 0;      // ์„ฑ๊ณต
x = false;  // ์˜ค๋ฅ˜: ๋ถˆ๋ฆฌ์–ธ(boolean)์—๋Š” ์ˆซ์ž๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์—†์Œ

์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ JSDoc ํŒจํ„ด ๋ชฉ๋ก์€ ์ด๊ณณ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ๋ณธ๋ฌธ์˜ ํ• ๋‹น์—์„œ ์ถ”๋ก ๋œ ํ”„๋กœํผํ‹ฐ (Properties are inferred from assignments in class bodies)

ES2015์—๋Š” ํด๋ž˜์Šค์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋‹จ์ด ์—†์Šต๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ๋Š” ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๊ณผ ๊ฐ™์ด ๋™์ ์œผ๋กœ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.

.js ํŒŒ์ผ์—์„œ, ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํด๋ž˜์Šค ๋ณธ๋ฌธ ๋‚ด๋ถ€์—์„œ ํ• ๋‹น๋œ ํ”„๋กœํผํ‹ฐ๋กœ๋ถ€ํ„ฐ ํ”„๋กœํผํ‹ฐ๋“ค์„ ์ถ”๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ƒ์„ฑ์ž๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š๊ฑฐ๋‚˜, ์ƒ์„ฑ์ž์—์„œ ์ •์˜๋œ ํƒ€์ž…์ด undefined๋‚˜ null์ด ์•„๋‹ ๊ฒฝ์šฐ, ํ”„๋กœํผํ‹ฐ์˜ ํƒ€์ž…์€ ์ƒ์„ฑ์ž์—์„œ ์ฃผ์–ด์ง„ ํƒ€์ž…๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ „์ž์— ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ์˜ ๊ฒฝ์šฐ, ํ• ๋‹น๋˜์—ˆ๋˜ ๋ชจ๋“  ๊ฐ’๋“ค์˜ ํƒ€์ž…์„ ๊ฐ€์ง„ ์œ ๋‹ˆ์–ธ ํƒ€์ž…์ด ๋ฉ๋‹ˆ๋‹ค. ์ƒ์„ฑ์ž์— ์ •์˜๋œ ํ”„๋กœํผํ‹ฐ๋Š” ํ•ญ์ƒ ์กด์žฌํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ€์ •ํ•˜๋Š” ๋ฐ˜๋ฉด, ๋ฉ”์„œ๋“œ, getter, setter์—์„œ๋งŒ ์ •์˜๋œ ํ”„๋กœํผํ‹ฐ๋Š” ์„ ํƒ์ ์ธ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค.

class C {
    constructor() {
        this.constructorOnly = 0
        this.constructorUnknown = undefined
    }
    method() {
        this.constructorOnly = false // ์˜ค๋ฅ˜, constructorOnly๋Š” Number ํƒ€์ž…์ž„
        this.constructorUnknown = "plunkbat" // ์„ฑ๊ณต, constructorUnknown์˜ ํƒ€์ž…์€ string | undefined
        this.methodOnly = 'ok'  // ์„ฑ๊ณต, ๊ทธ๋Ÿฌ๋‚˜ methodOnly๋Š” undefined ํƒ€์ž… ๋˜ํ•œ ํ—ˆ์šฉ๋จ
    }
    method2() {
        this.methodOnly = true  // ์ด ๋˜ํ•œ ์„ฑ๊ณต, methodOnly์˜ ํƒ€์ž…์€ string | boolean | undefined
    }
}

ํ”„๋กœํผํ‹ฐ๊ฐ€ ํด๋ž˜์Šค ๋ณธ๋ฌธ์—์„œ ์„ค์ •๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ์•Œ ์ˆ˜ ์—†๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค์— ์ฝ๊ธฐ ์ „์šฉ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, ์ƒ์„ฑ์ž์—์„œ ์„ ์–ธ์— JSDoc์„ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž…์„ ์ถ”๊ฐ€ํ•˜์—ฌ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„์—” ์ดˆ๊ธฐํ™”ํ•˜๋”๋ผ๋„ ๊ฐ’์„ ์ง€์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

class C {
    constructor() {
        /** @type {number | undefined} */
        this.prop = undefined;
        /** @type {number | undefined} */
        this.count;
    }
}

let c = new C();
c.prop = 0;          // ์„ฑ๊ณต
c.count = "string";  // ์˜ค๋ฅ˜: string ์€ number|undefined์— ํ• ๋‹นํ•  ์ˆ˜ ์—†์Œ

์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ ํด๋ž˜์Šค๋Š” ๋™์ผ (Constructor functions are equivalent to classes)

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

function C() {
    this.constructorOnly = 0
    this.constructorUnknown = undefined
}
C.prototype.method = function() {
    this.constructorOnly = false // ์˜ค๋ฅ˜
    this.constructorUnknown = "plunkbat" // ์„ฑ๊ณต, ํƒ€์ž…์€ string | undefined๊ฐ€ ๋จ
}

CommonJS ๋ชจ๋“ˆ ์ง€์› (CommonJS modules are supported)

.js ํŒŒ์ผ์—์„œ, TypeScript๋Š” CommonJS ๋ชจ๋“ˆ ํฌ๋งท์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. exports์™€ module.exports ํ• ๋‹น์€ export ์„ ์–ธ์œผ๋กœ ์ธ์‹๋ฉ๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, require ํ•จ์ˆ˜ ํ˜ธ์ถœ์€ ๋ชจ๋“ˆ import๋กœ ์ธ์‹๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

// `import module "fs"`์™€ ๊ฐ™์Œ
const fs = require("fs");

// `export function readFile`๊ณผ ๊ฐ™์Œ
module.exports.readFile = function(f) {
    return fs.readFileSync(f);
}

JavaScript์˜ ๋ชจ๋“ˆ ์ง€์›์€ TypeScript์˜ ๋ชจ๋“ˆ ์ง€์›๋ณด๋‹ค ๊ตฌ๋ฌธ์ ์œผ๋กœ ํ›จ์”ฌ ๊ด€์šฉ์ ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋Œ€๋ถ€๋ถ„์˜ ํ• ๋‹น๊ณผ ์„ ์–ธ์˜ ์กฐํ•ฉ์ด ์ง€์›๋ฉ๋‹ˆ๋‹ค.

ํด๋ž˜์Šค, ํ•จ์ˆ˜, ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค (Classes, functions, and object literals are namespaces)

.js ํŒŒ์ผ์— ์žˆ๋Š” ํด๋ž˜์Šค๋Š” ๋„ค์ž„์ŠคํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํด๋ž˜์Šค๋ฅผ ์ค‘์ฒฉํ•˜๋Š” ๋ฐ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

class C {
}
C.D = class {
}

๊ทธ๋ฆฌ๊ณ  ES2015 ์ด์ „ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ, ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐ์— ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:

function Outer() {
  this.y = 2
}
Outer.Inner = function() {
  this.yy = 2
}

๋˜ํ•œ ๊ฐ„๋‹จํ•œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ์— ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:

var ns = {}
ns.C = class {
}
ns.func = function() {
}

๋‹ค๋ฅธ ๋ฒˆํ˜•๋„ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค:

// ์ฆ‰์‹œ ํ˜ธ์ถœ ํ•จ์ˆ˜(IIFE)
var ns = (function (n) {
  return n || {};
})();
ns.CONST = 1

// ์ „์—ญ์œผ๋กœ ๊ธฐ๋ณธ ์„ค์ •
var assign = assign || function() {
  // ์—ฌ๊ธฐ์—” ์ฝ”๋“œ๋ฅผ
}
assign.extra = 1

๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์€ ํ™•์žฅ ๊ฐ€๋Šฅ (Object literals are open-ended)

.ts ํŒŒ์ผ์—์„œ, ๋ณ€์ˆ˜ ์„ ์–ธ์„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์€ ์„ ์–ธ์— ํ•ด๋‹น ํƒ€์ž…์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค. ์›๋ณธ ๋ฆฌํ„ฐ๋Ÿด์— ๋ช…์‹œ๋˜์–ด ์žˆ์ง€ ์•Š์€ ์ƒˆ ๋ฉค๋ฒ„๋Š” ์ถ”๊ฐ€๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด ๊ทœ์น™์€ .js ํŒŒ์ผ์—์„  ์™„ํ™”๋ฉ๋‹ˆ๋‹ค; ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์€ ์›๋ณธ์— ์ •์˜๋˜์ง€ ์•Š์€ ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋ฅผ ์กฐํšŒํ•˜๊ณ  ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ํ—ˆ์šฉ๋˜๋Š” ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ํƒ€์ž…(์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜)์„ ๊ฐ–์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

var obj = { a: 1 };
obj.b = 2;  // ํ—ˆ์šฉ๋จ

๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์€ ๋งˆ์น˜ ๋‹ซํžŒ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ์—ด๋ฆฐ ๋งต(maps)์œผ๋กœ ๋‹ค๋ค„์ง€๋„๋ก [x:string]: any์™€ ๊ฐ™์€ ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๊ฐ€์ง„ ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ํŠน์ • JavaScript ๊ฒ€์‚ฌ ๋™์ž‘๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ํ•ด๋‹น ๋™์ž‘์€ ๋ณ€์ˆ˜์— JSDoc ํƒ€์ž…์„ ์ง€์ •ํ•˜์—ฌ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

/** @type {{a: number}} */
var obj = { a: 1 };
obj.b = 2;  // ์˜ค๋ฅ˜, {a: number}ํƒ€์ž…์—” b ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†์Œ

null, undefined ๋ฐ ๋นˆ ๋ฐฐ์—ด ์ด๋‹ˆ์…œ๋ผ์ด์ €๋Š” any ํ˜น์€ any[] ํƒ€์ž… (null, undefined, and empty array initializers are of type any or any[])

null ๋˜๋Š” undefined๋กœ ์ดˆ๊ธฐํ™”๋œ ๋ณ€์ˆ˜๋‚˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋˜๋Š” ํ”„๋กœํผํ‹ฐ๋Š”, ์—„๊ฒฉํ•œ null ๊ฒ€์‚ฌ๊ฐ€ ์žˆ๋”๋ผ๋„ any ํƒ€์ž…์„ ๊ฐ–๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. []๋กœ ์ดˆ๊ธฐํ™”๋œ ๋ณ€์ˆ˜๋‚˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋˜๋Š” ํ”„๋กœํผํ‹ฐ๋Š”, ์—„๊ฒฉํ•œ null ๊ฒ€์‚ฌ๊ฐ€ ์žˆ๋”๋ผ๋„ any[] ํƒ€์ž…์„ ๊ฐ–๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์œ„์—์„œ ์„ค๋ช…ํ•œ ์—ฌ๋Ÿฌ ์ด๋‹ˆ์…œ๋ผ์ด์ €(initializer)๋ฅผ ๊ฐ–๋Š” ํ”„๋กœํผํ‹ฐ๋งŒ์ด ์œ ์ผํ•œ ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค.

function Foo(i = null) {
    if (!i) i = 1;
    var j = undefined;
    j = 2;
    this.l = [];
}
var foo = new Foo();
foo.l.push(foo.i);
foo.l.push("end");

ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ ํƒ ์‚ฌํ•ญ (Function parameters are optional by default)

ES2015 ์ด์ „์˜ JavaScript๋Š” ์„ ํƒ์ ์ธ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•  ๋ฐฉ๋ฒ•์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, .js ํŒŒ์ผ์—์„  ๋ชจ๋“  ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์„ ํƒ์ ์ธ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. ์„ ์–ธ๋œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ณด๋‹ค ์ ์€ ์ธ์ˆ˜๋กœ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋„ˆ๋ฌด ๋งŽ์€ ์ธ์ˆ˜๋ฅผ ๋„ฃ์–ด ํ˜ธ์ถœํ•˜๋ฉด ์˜ค๋ฅ˜๋ฅผ ์ผ์œผํ‚จ๋‹ค๋Š” ๊ฒƒ์— ์œ ์˜ํ•˜์„ธ์š”.

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

function bar(a, b) {
    console.log(a + " " + b);
}

bar(1);       // ์„ฑ๊ณต, ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ์„ ํƒ ์‚ฌํ•ญ์ž„
bar(1, 2);
bar(1, 2, 3); // ์˜ค๋ฅ˜, ์ธ์ˆ˜์˜ ๊ฐฏ์ˆ˜๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์Œ

JSDoc ํ‘œ์‹œ๊ฐ€ ๋œ ํ•จ์ˆ˜๋Š” ์ด ๊ทœ์น™์—์„œ ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค. JSDoc์˜ ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ ํƒ ์‚ฌํ•ญ์„ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ์‹œ:

/**
 * @param {string} [somebody] - ๋ˆ„๊ตฐ๊ฐ€์˜ ์ด๋ฆ„
 */
function sayHello(somebody) {
    if (!somebody) {
        somebody = 'John Doe';
    }
    console.log('Hello ' + somebody);
}

sayHello();

arguments ์‚ฌ์šฉ์œผ๋กœ๋ถ€ํ„ฐ ์ถ”๋ก ๋œ var-args ๋งค๊ฐœ๋ณ€์ˆ˜ ์„ ์–ธ (Var-args parameter declaration inferred from use of arguments)

arguments ์ฐธ์กฐ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ณธ๋ฌธ์„ ๊ฐ€์ง„ ํ•จ์ˆ˜๋Š”, ์•”๋ฌต์ ์œผ๋กœ var-args ๋งค๊ฐœ๋ณ€์ˆ˜(์˜ˆ: (...arg: any[]) => any)๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. JSDoc์˜ var-args ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ˆ˜์˜ ํƒ€์ž…์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

/** @param {...number} args */
function sum(/* numbers */) {
    var total = 0
    for (var i = 0; i < arguments.length; i++) {
      total += arguments[i]
    }
    return total
}

ํƒ€์ž…์ด ์ง€์ •๋˜์ง€ ์•Š์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ any์ž„ (Unspecified type parameters default to any)

JavaScript์—๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž…์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ตฌ๋ฌธ์ด ์—†์œผ๋ฏ€๋กœ, ํƒ€์ž…์ด ์ง€์ •๋˜์ง€ ์•Š์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ any ํƒ€์ž…์ž…๋‹ˆ๋‹ค.

ํ™•์žฅ ์ ˆ์—์„œ (In extends clause)

์˜ˆ๋ฅผ ๋“ค์–ด, React.Component๋Š” Props์™€ State๋ผ๋Š” ๋‘ ํƒ€์ž…์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ–๋„๋ก ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. .js ํŒŒ์ผ์—๋Š” ์ด๋Ÿฌํ•œ ๊ฒƒ๋“ค์„ ํ™•์žฅ ์ ˆ์— ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์ •๋‹นํ•œ ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•ด๋‹น ํƒ€์ž… ์ธ์ˆ˜๋Š” any๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค:

import { Component } from "react";

class MyComponent extends Component {
    render() {
        this.props.b; // this.props์˜ ํƒ€์ž…์ด any์ด๋ฏ€๋กœ ํ—ˆ์šฉ๋จ
    }
}

ํƒ€์ž…์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜๋ ค๋ฉด JSDoc์˜ @augments๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด:

import { Component } from "react";

/**
 * @augments {Component<{a: number}, State>}
 */
class MyComponent extends Component {
    render() {
        this.props.b; // ์˜ค๋ฅ˜: b ๋Š” {a:number}์— ์†ํ•˜์ง€ ์•Š์Œ
    }
}

JSDoc ์ฐธ์กฐ์—์„œ (In JSDoc references)

JSDoc์˜ ์ง€์ •๋˜์ง€ ์•Š์€ ํƒ€์ž… ์ธ์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ any์ž…๋‹ˆ๋‹ค:

/** @type{Array} */
var x = [];

x.push(1);        // ์„ฑ๊ณต
x.push("string"); // ์„ฑ๊ณต, x๋Š” Array<any> ํƒ€์ž…์ž„

/** @type{Array.<number>} */
var y = [];

y.push(1);        // ์„ฑ๊ณต
y.push("string"); // ์˜ค๋ฅ˜, string์„ number ํƒ€์ž…์— ํ• ๋‹นํ•  ์ˆ˜ ์—†์Œ

ํ•จ์ˆ˜ ํ˜ธ์ถœ์—์„œ (In function calls)

์ œ๋„ค๋ฆญ ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ์€ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๋ก ํ•ฉ๋‹ˆ๋‹ค. ๋•Œ๋•Œ๋กœ ์ด ๊ณผ์ •์€ ์ถ”๋ก  ์†Œ์Šค๊ฐ€ ๋ถ€์กฑํ•˜์—ฌ ์–ด๋– ํ•œ ํƒ€์ž…๋„ ์ถ”๋ก ํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค; ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ, ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…์€ ๊ธฐ๋ณธ์ ์œผ๋กœ any์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

var p = new Promise((resolve, reject) => { reject() });

p; // Promise<any>;

์ง€์›๋˜๋Š” JSDoc (Supported JSDoc)

์•„๋ž˜์˜ ๊ตฌ์„ฑ์€ JavaScript ํŒŒ์ผ์—์„œ JSDoc ์ฃผ์„์„ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž… ์ •๋ณด๋ฅผ ์ œ๊ณตํ•  ๋•Œ ์ง€์›๋˜๋Š” ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

์•„๋ž˜์— ๋ช…์‹œ๋˜์ง€ ์•Š์€ ํƒœ๊ทธ(@async ๋“ฑ)๋Š” ์•„์ง ์ง€์›๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”.

  • @type
  • @param (๋˜๋Š” @arg ๋˜๋Š” @argument)
  • @returns (๋˜๋Š” @return)
  • @typedef
  • @callback
  • @template
  • @class (๋˜๋Š” @constructor)
  • @this
  • @extends (๋˜๋Š” @augments)
  • @enum

๋Œ€๋ถ€๋ถ„์˜ ํƒœ๊ทธ์˜ ์˜๋ฏธ๋Š” usejsdoc.org์—์„œ ์„ค๋ช…ํ•˜๋Š” ํƒœ๊ทธ์˜ ์˜๋ฏธ์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์˜ ์ฝ”๋“œ๋Š” ์ฐจ์ด์ ์„ ์„ค๋ช…ํ•˜๊ณ  ๊ฐ ํƒœ๊ทธ์˜ ์‚ฌ์šฉ ์˜ˆ์‹œ๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

@type

"@type" ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ํƒ€์ž… ์ด๋ฆ„์„ ์ฐธ์กฐ(์›๋ž˜ TypeScript์˜ ์„ ์–ธ์— ์ •์˜๋œ ๊ฒƒ ๋˜๋Š” JSDoc์˜ "@typedef" ํƒœ๊ทธ ์ค‘ ํ•˜๋‚˜)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  TypeScript์˜ ํƒ€์ž…, ๋Œ€๋ถ€๋ถ„์˜ JSDoc ํƒ€์ž… ์ค‘ ์–ด๋–ค ๊ฒƒ์ด๋“  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

/**
 * @type {string}
 */
var s;

/** @type {Window} */
var win;

/** @type {PromiseLike<string>} */
var promisedString;

// HTML ์š”์†Œ๋ฅผ DOM ํ”„๋กœํผํ‹ฐ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Œ
/** @type {HTMLElement} */
var myElement = document.querySelector(selector);
element.dataset.myData = '';

@type์€ ์œ ๋‹ˆ์–ธ ํƒ€์ž…์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค; ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฌธ์ž์—ด๊ณผ ๋ถˆ๋ฆฌ์–ธ ์ค‘ ์–ด๋–ค ๊ฒƒ์ด๋“  ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

/**
 * @type {(string | boolean)}
 */
var sb;

์œ ๋‹ˆ์–ธ ํƒ€์ž…์—๋Š” ๊ด„ํ˜ธ๊ฐ€ ์„ ํƒ ์‚ฌํ•ญ์ด๋ผ๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”.

/**
 * @type {string | boolean}
 */
var sb;

๋‹ค์–‘ํ•œ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐ์—ด ํƒ€์ž…์„ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:

/** @type {number[]} */
var ns;
/** @type {Array.<number>} */
var nds;
/** @type {Array<number>} */
var nas;

๋˜ํ•œ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์„ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ”„๋กœํผํ‹ฐ 'a' (string) ์™€ 'b' (number)๋ฅผ ๊ฐ–๋Š” ์˜ค๋ธŒ์ ํŠธ๋ผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

/** @type {{ a: string, b: number }} */
var var9;

ํ‘œ์ค€ JSDoc ๊ตฌ๋ฌธ ๋˜๋Š” TypeScript ๊ตฌ๋ฌธ์„ ํ†ตํ•ด ๋ฌธ์ž์—ด ํ˜น์€ ์ˆซ์ž ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์œ ์‚ฌ-๋งต ํ˜น์€ ์œ ์‚ฌ-๋ฐฐ์—ด ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

/**
 * ์ž„์˜์˜ `string` ํ”„๋กœํผํ‹ฐ๋ฅผ `number`์— ๋งคํ•‘ํ•˜๋Š” ์œ ์‚ฌ-๋งต ๊ฐ์ฒด.
 *
 * @type {Object.<string, number>}
 */
var stringToNumber;

/** @type {Object.<number, object>} */
var arrayLike;

์•ž์˜ ๋‘ ํƒ€์ž…์€ TypeScript์˜ { [x: string]: number } ๊ทธ๋ฆฌ๊ณ  { [x: number]: any }์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋‘ ๊ตฌ๋ฌธ์„ ๋ชจ๋‘ ์ดํ•ดํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ•จ์ˆ˜ ํƒ€์ž…์€ TypeScript ๋˜๋Š” ํด๋กœ์ € ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

/** @type {function(string, boolean): number} Closure ๊ตฌ๋ฌธ */
var sbn;
/** @type {(s: string, b: boolean) => number} TypeScript ๊ตฌ๋ฌธ */
var sbn2;

ํ˜น์€ ๋‹จ์ˆœํžˆ ์ง€์ •๋˜์ง€ ์•Š์€ Function ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค:

/** @type {Function} */
var fn7;
/** @type {function} */
var fn6;

Closure์˜ ๋‹ค๋ฅธ ํƒ€์ž… ๋˜ํ•œ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค:

/**
 * @type {*} - ์–ด๋– ํ•œ ํƒ€์ž…์ด๋“  ๋  ์ˆ˜ ์žˆ์Œ
 */
var star;
/**
 * @type {?} - ์‹๋ณ„๋˜์ง€ ์•Š์€ ํƒ€์ž… ('any'์™€ ๊ฐ™์Œ)
 */
var question;

์บ์ŠคํŠธ (Casts)

TypeScript๋Š” ํด๋กœ์ €์˜ ์บ์ŠคํŠธ(cast) ๊ตฌ๋ฌธ์„ ์ฐจ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ด„ํ˜ธํ™”๋œ ํ‘œํ˜„์‹ ์•ž์— @type ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ํƒ€์ž…์œผ๋กœ์˜ ์บ์ŠคํŠธ๋ฅผ ๊ฐ€๋Šฅ์ผ€ ํ•ฉ๋‹ˆ๋‹ค.

/**
 * @type {number | string}
 */
var numberOrString = Math.random() < 0.5 ? "hello" : 100;
var typeAssertedNumber = /** @type {number} */ (numberOrString)

ํƒ€์ž… import (Import types)

ํƒ€์ž… import๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ํŒŒ์ผ์˜ ์„ ์–ธ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ตฌ๋ฌธ์€ TypeScript์— ํŠนํ™”๋œ ๊ฒƒ์ด๋ฉฐ JSDoc ํ‘œ์ค€๊ณผ๋Š” ์กฐ๊ธˆ ๋‹ค๋ฆ…๋‹ˆ๋‹ค:

/**
 * @param p { import("./a").Pet }
 */
function walk(p) {
    console.log(`Walking ${p.name}...`);
}

ํƒ€์ž… import๋Š” ํƒ€์ž… ๋ณ„์นญ ์„ ์–ธ์—์„œ๋„ ์“ฐ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

/**
 * @typedef { import("./a").Pet } Pet
 */

/**
 * @type {Pet}
 */
var myPet;
myPet.name;

ํƒ€์ž…์„ ๋ชจ๋ฅด๊ฑฐ๋‚˜ ์ž…๋ ฅํ•˜๊ธฐ ๊ท€์ฐฎ์€ ํฐ ํƒ€์ž…์ด ์žˆ์„ ๊ฒฝ์šฐ, ํƒ€์ž… import๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“ˆ์—์„œ ๊ฐ’์˜ ํƒ€์ž…์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

/**
 * @type {typeof import("./a").x }
 */
var x = require("./a").x;

@param and @returns

@param์€ @type๊ณผ ๊ฐ™์€ ์ข…๋ฅ˜์˜ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ด๋ฆ„์„ ๋Œ€๊ด„ํ˜ธ๋กœ ๋‘˜๋Ÿฌ์‹ธ์„œ ์„ ํƒ์ ์œผ๋กœ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

// ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ๊ตฌ๋ฌธ์œผ๋กœ ์„ ์–ธ๋  ์ˆ˜ ์žˆ์Œ
/**
 * @param {string}  p1 - ๋ฌธ์ž์—ด ๋งค๊ฐœ๋ณ€์ˆ˜.
 * @param {string=} p2 - ์„ ํƒ์  ๋ฌธ์ž์—ด ๋งค๊ฐœ๋ณ€์ˆ˜ (ํด๋กœ์ € ๊ตฌ๋ฌธ)
 * @param {string} [p3] - ๋˜๋‹ค๋ฅธ ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜ (JSDoc ๊ตฌ๋ฌธ).
 * @param {string} [p4="test"] - ๊ธฐ๋ณธ๊ฐ’์„ ๊ฐ€์ง„ ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜
 * @return {string} ๊ฒฐ๊ณผ
 */
function stringsStringStrings(p1, p2, p3, p4){
  // TODO
}

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์œผ๋กœ๋Š”:

/**
 * @return {PromiseLike<string>}
 */
function ps(){}

/**
 * @returns {{ a: string, b: number }} - '@returns'๊ณผ '@return' ๋ชจ๋‘ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
 */
function ab(){}

@typedef, @callback, and @param

@typedef๋ฅผ ์‚ฌ์šฉํ•ด ๋ณต์žกํ•œ ํƒ€์ž…์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. @param๊ณผ ๋น„์Šทํ•œ ๊ตฌ๋ฌธ์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

/**
 * @typedef {Object} SpecialType - 'SpecialType'์ด๋ผ๋Š” ์ƒˆ ํƒ€์ž…์„ ์ƒ์„ฑ
 * @property {string} prop1 - SpecialType์˜ ๋ฌธ์ž์—ด ํ”„๋กœํผํ‹ฐ
 * @property {number} prop2 - SpecialType์˜ ์ˆซ์ž ํ”„๋กœํผํ‹ฐ
 * @property {number=} prop3 - SpecialType์˜ ์„ ํƒ์  ์ˆซ์ž ํ”„๋กœํผํ‹ฐ
 * @prop {number} [prop4] - SpecialType์˜ ์„ ํƒ์  ์ˆซ์ž ํ”„๋กœํผํ‹ฐ
 * @prop {number} [prop5=42] - SpecialType์˜ ๊ธฐ๋ณธ๊ฐ’์„ ๊ฐ€์ง„ ์„ ํƒ์  ์ˆซ์ž ํ”„๋กœํผํ‹ฐ
 */
/** @type {SpecialType} */
var specialTypeObject;

์ฒซ ๋ฒˆ์งธ ์ค„์— object๋‚˜ Object๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

/**
 * @typedef {object} SpecialType1 - 'SpecialType1'์ด๋ผ๋Š” ์ƒˆ ํƒ€์ž… ์ƒ์„ฑ
 * @property {string} prop1 - SpecialType1์˜ ๋ฌธ์ž์—ด ํ”„๋กœํผํ‹ฐ
 * @property {number} prop2 - SpecialType1์˜ ์ˆซ์ž ํ”„๋กœํผํ‹ฐ
 * @property {number=} prop3 - SpecialType1์˜ ์„ ํƒ์  ์ˆซ์ž ํ”„๋กœํผํ‹ฐ
 */
/** @type {SpecialType1} */
var specialTypeObject1;

@param์€ ์ผํšŒ์„ฑ์ธ ํƒ€์ž… ์ง€์ •์— ๋Œ€ํ•œ ๋น„์Šทํ•œ ๊ตฌ๋ฌธ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ค‘์ฒฉ๋œ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„ ์•ž์—” ๋งค๊ฐœ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ๋ถ™์—ฌ์•ผ ํ•จ์„ ์œ ์˜ํ•˜์„ธ์š”:

/**
 * @param {Object} options - ํ•ด๋‹น ํ˜•ํƒœ๋Š” ์œ„์˜ SpecialType๊ณผ ๋™์ผ
 * @param {string} options.prop1
 * @param {number} options.prop2
 * @param {number=} options.prop3
 * @param {number} [options.prop4]
 * @param {number} [options.prop5=42]
 */
function special(options) {
  return (options.prop4 || 1001) + options.prop5;
}

@callback์€ @typedef์™€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค๋งŒ, ๊ฐ์ฒด ํƒ€์ž… ๋Œ€์‹  ํ•จ์ˆ˜์˜ ํƒ€์ž…์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค:

/**
 * @callback Predicate
 * @param {string} data
 * @param {number} [index]
 * @returns {boolean}
 */
/** @type {Predicate} */
const ok = s => !(s.length % 2);

๋ฌผ๋ก , ์ด๋Ÿฌํ•œ ์œ ํ˜• ์ค‘ ์–ด๋–ค ๊ฒƒ์ด๋ผ๋„ ๋‹จ์ผ ๋ผ์ธ์˜ @typedef TypeScript ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•ด ์„ ์–ธ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

/** @typedef {{ prop1: string, prop2: string, prop3?: number }} SpecialType */
/** @typedef {(data: string, index?: number) => boolean} Predicate */

@template

@template ํƒœ๊ทธ๋กœ ์ œ๋„ค๋ฆญ ํƒ€์ž…์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

/**
 * @template T
 * @param {T} x - ๋ฆฌํ„ด ํƒ€์ž…๊นŒ์ง€ ์‚ฌ์šฉ๋˜๋Š” ์ œ๋„ค๋ฆญ ๋งค๊ฐœ๋ณ€์ˆ˜
 * @return {T}
 */
function id(x){ return x }

์ฝค๋งˆ ๋˜๋Š” ์—ฌ๋Ÿฌ ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

/**
 * @template T,U,V
 * @template W,X
 */

ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜ ์ด๋ฆ„ ์•ž์— ํƒ€์ž… ์ œ์•ฝ ์กฐ๊ฑด์„ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชฉ๋ก์˜ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…๋งŒ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค:

/**
 * @template {string} K - K๋Š” ๋ฌธ์ž์—ด ํ˜น์€ ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์ด์–ด์•ผ๋งŒ ํ•จ
 * @template {{ serious(): string }} Seriousalizable - serious ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ ธ์•ผ๋งŒ ํ•จ
 * @param {K} key
 * @param {Seriousalizable} object
 */
function seriousalize(key, object) {
  // ????
}

@constructor

์ปดํŒŒ์ผ๋Ÿฌ๋Š” this-ํ”„๋กœํผํ‹ฐ ํ• ๋‹น์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ถ”๋ก ํ•ฉ๋‹ˆ๋‹ค๋งŒ, @constructor ํƒœ๊ทธ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ณด๋‹ค ์—„๊ฒฉํ•œ ๊ฒ€์‚ฌ์™€ ๋” ๋‚˜์€ ์ œ์•ˆ์ด ๋˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

/**
 * @constructor
 * @param {number} data
 */
function C(data) {
  this.size = 0;
  this.initialize(data); // ์ด๋‹ˆ์…œ๋ผ์ด์ €์— ๋ฌธ์ž์—ด์ด ๋“ค์–ด๊ฐˆ ๊ฒฝ์šฐ, ์˜ค๋ฅ˜ ๋ฐœ์ƒ ๊ฐ€๋Šฅ
}
/**
 * @param {string} s
 */
C.prototype.initialize = function (s) {
  this.size = s.length
}

var c = new C(0);
var result = C(1); // C๋Š” ์ƒˆ ์ธ์Šคํ„ด์Šค๋กœ๋งŒ ํ˜ธ์ถœํ•ด์•ผ ํ•จ

@constructor๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, this๋Š” C์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ๊ฒ€์‚ฌ๋˜๋ฏ€๋กœ, initailize ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•˜์—ฌ ์•Œ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ฉฐ ์ˆซ์ž๋ฅผ ๋„˜๊ธธ ๊ฒฝ์šฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ C๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ ์˜ค๋ฅ˜๋ฅผ ์ผ์œผํ‚ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ถˆํ–‰ํ•˜๊ฒŒ๋„, ์ด๋Š” ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” @constructor๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

@this

์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋Œ€๊ฒŒ ์ž‘์—…ํ•  ์ปจํ…์ŠคํŠธ๊ฐ€ ์žˆ์„ ๋•Œ this์˜ ํƒ€์ž…์„ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ, @this๋ฅผ ์‚ฌ์šฉํ•ด this์˜ ํƒ€์ž…์„ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

/**
 * @this {HTMLElement}
 * @param {*} e
 */
function callbackForLater(e) {
    this.clientHeight = parseInt(e) // ์ž˜ ๋˜์–ด์•ผ ํ•จ!
}

@extends

JavaScript ํด๋ž˜์Šค์—” ์ œ๋„ค๋ฆญ ๊ธฐ์ดˆ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•  ๋•Œ, ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์–ด๋–ค ํƒ€์ž…์ด ๋˜์–ด์•ผ ํ•˜๋Š”์ง€ ์ง€์ •ํ•  ๊ณณ์ด ์—†์Šต๋‹ˆ๋‹ค. @extends ํƒœ๊ทธ๋Š” ํ•ด๋‹น ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…์— ๋Œ€ํ•œ ์œ„์น˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค:

/**
 * @template T
 * @extends {Set<T>}
 */
class SortableSet extends Set {
  // ...
}

@extends๋Š” ํด๋ž˜์Šค์—์„œ๋งŒ ์ž‘๋™ํ•œ๋‹ค๋Š” ์ ์„ ์•Œ์•„๋‘์„ธ์š”. ํ˜„์žฌ๋กœ์„œ๋Š”, ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค.

@enum

@enum ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ๋ฉค๋ฒ„๊ฐ€ ๋ชจ๋‘ ์ง€์ •๋œ ํƒ€์ž…์ธ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ JavaScript ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ, ๋‹ค๋ฅธ ๋ฉค๋ฒ„๋Š” ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

/** @enum {number} */
const JSDocState = {
  BeginningOfLine: 0,
  SawAsterisk: 1,
  SavingComments: 2,
}

@enum์€ TypeScript์˜ enum ๊ณผ๋Š” ๊ฝค ๋‹ค๋ฅด๋ฉฐ, ํ›จ์”ฌ ๋‹จ์ˆœํ•˜๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”. ๊ทธ๋Ÿฌ๋‚˜ TypeScript์˜ ์—ด๊ฑฐํ˜•๊ณผ๋Š” ๋‹ฌ๋ฆฌ, @enum์€ ์–ด๋– ํ•œ ํƒ€์ž…์ด๋“  ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

/** @enum {function(number): number} */
const Math = {
  add1: n => n + 1,
  id: n => -n,
  sub1: n => n - 1,
}

๋‹ค๋ฅธ ์˜ˆ์ œ๋“ค (More examples)

var someObj = {
  /**
   * @param {string} param1 - ํ”„๋กœํผํ‹ฐ ํ• ๋‹น์— ๋Œ€ํ•œ Docs
   */
  x: function(param1){}
};

/**
 * ๋ณ€์ˆ˜ ํ• ๋‹น์— ๋Œ€ํ•œ docs์ฒ˜๋Ÿผ
 * @return {Window}
 */
let someFunc = function(){};

/**
 * ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ
 * @param {string} greeting ์‚ฌ์šฉํ•  ์ธ์‚ฌ๋ง
 */
Foo.prototype.sayHi = (greeting) => console.log("Hi!");

/**
 * ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ํ‘œํ˜„
 * @param {number} x - A multiplier
 */
let myArrow = x => x * x;

/**
 * JSX์˜ ๋ฌด์ƒํƒœ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ ์‚ฌ์šฉ๋จ.
 * @param {{a: string, b: number}} test - Some param
 */
var fc = (test) => <div>{test.a.charAt(0)}</div>;

/**
 * ํด๋กœ์ € ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ, ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํด๋ž˜์Šค ์ƒ์„ฑ์ž๊ฐ€ ๋  ์ˆ˜ ์žˆ์Œ.
 *
 * @param {{new(...args: any[]): object}} C - ๋“ฑ๋กํ•  ํด๋ž˜์Šค
 */
function registerClass(C) {}

/**
 * @param {...string} p1 - A 'rest' arg (array) of strings. ('any'๋กœ ์ทจ๊ธ‰๋จ)
 */
function fn10(p1){}

/**
 * @param {...string} p1 - A 'rest' arg (array) of strings. ('any'๋กœ ์ทจ๊ธ‰๋จ)
 */
function fn9(p1) {
  return p1.join();
}

์ง€์›๋˜์ง€ ์•Š์„ ๊ฒƒ์œผ๋กœ ์•Œ๋ ค์ง„ ํŒจํ„ด๋“ค (Patterns that are known NOT to be supported)

์ƒ์„ฑ์ž ํ•จ์ˆ˜์ฒ˜๋Ÿผ, ๊ฐ’ ๊ณต๊ฐ„(value space)์— ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ํƒ€์ž…์œผ๋กœ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์€ ๊ฐ์ฒด๊ฐ€ ํƒ€์ž…์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š” ํ•œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

function aNormalFunction() {

}
/**
 * @type {aNormalFunction}
 */
var wrong;
/**
 * 'typeof' ๋Œ€์‹  ์‚ฌ์šฉ:
 * @type {typeof aNormalFunction}
 */
var right;

์ ‘๋ฏธ์‚ฌ๋Š” ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ์œ ํ˜•์˜ ํ”„๋กœํผํ‹ฐ ์œ ํ˜•๊ณผ ๋™์ผํ•˜๋ฉฐ ์„ ํƒ์  ํ”„๋กœํผํ‹ฐ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค:

/**
 * @type {{ a: string, b: number= }}
 */
var wrong;
/**
 * ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„์— ๋ฌผ์Œํ‘œ ์ ‘๋ฏธ์‚ฌ ์‚ฌ์šฉ
 * @type {{ a: string, b?: number }}
 */
var right;

Nullable ํƒ€์ž…์€ strictNullChecks์ด ํ™œ์„ฑํ™”๋˜์–ด์žˆ๋Š” ๋•Œ๋งŒ ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

/**
 * @type {?number}
 * With strictNullChecks: true -- number | null
 * With strictNullChecks: off  -- number
 */
var nullable;

Nullable์ด ์•„๋‹Œ ํƒ€์ž…์€ ์˜๋ฏธ๊ฐ€ ์—†์œผ๋ฉฐ ์›๋ž˜์˜ ํƒ€์ž…์œผ๋กœ ์ทจ๊ธ‰๋ฉ๋‹ˆ๋‹ค:

/**
 * @type {!number}
 * ๋‹จ์ˆœํžˆ ์ˆซ์ž ํƒ€์ž…์„ ๊ฐ–๊ฒŒ ๋จ
 */
var normal;

JSDoc์˜ ํƒ€์ž… ์‹œ์Šคํ…œ๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ, TypeScript๋Š” null ๊ฐ’์„ ํฌํ•จํ•˜๋Š”์ง€, ์•ˆ ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด์„œ๋งŒ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ช…์‹œ์ ์ธ non-nullability๋Š” ์—†์Šต๋‹ˆ๋‹ค -- strictNullChecks์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋‹ค๋ฉด, number๋Š” nullable์ด ์•„๋‹ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ™œ์„ฑํ™”๋˜์–ด์žˆ์ง€ ์•Š๋‹ค๋ฉด, number๋Š” nullable ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.