TypeScript 2.3 ์ด์์ ๋ฒ์ ์์๋ --checkJs
๋ฅผ ์ฌ์ฉํดย .js
ํ์ผ์์ ํ์
๊ฒ์ฌ ๋ฐ ์ค๋ฅ ๋ณด๊ณ ๋ฅผ ์ง์ํฉ๋๋ค.
// @ts-nocheck
์ฃผ์์ ๋ฌ์ ์ผ๋ถ ํ์ผ์์ ํ์
๊ฒ์ฌ๋ฅผ ๊ฑด๋๋ธ ์ ์์ผ๋ฉฐ; ๋ฐ๋๋ก // @ts-check
์ฃผ์์ ๋ฌ์ --checkJs
๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์ผ๋ถ .js
ํ์ผ์ ๋ํด์๋ง ํ์
๊ฒ์ฌ๋ฅผ ํ๋๋ก ์ ํํ ์ ์์ต๋๋ค.
๋ํ ํน์ ๋ถ๋ถ์ ์ ์ค์ // @ts-ignore
๋ฅผ ๋ฌ์ ์๋ฌ๋ฅผ ๋ฌด์ํ ์๋ ์์ต๋๋ค.
tsconfig.json
์ด ์๋ ๊ฒฝ์ฐ, JavaScript ๊ฒ์ฌ๋ noImplicitAny
, strictNullChecks
๋ฑ์ ์๊ฒฉํ ํ๋๊ทธ๋ฅผ ์ฐ์ ์ํ๋ค๋ ์ ์ ์์๋์ธ์.
ํ์ง๋ง, JavaScript ๊ฒ์ฌ์ ์๋์ ์ธ ๋์จํจ ๋๋ถ์ ์๊ฒฉํ ํ๋๊ทธ์ ๊ฒฐํฉํ์ฌ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ผ์ด ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ค ๊ฒ์
๋๋ค.
.ts
ํ์ผ๊ณผ .js
ํ์ผ์ ํ์
์ ๊ฒ์ฌํ๋ ๋ฐฉ๋ฒ์ ๋ช ๊ฐ์ง ์ฃผ๋ชฉํ ๋งํ ์ฐจ์ด์ ์ด ์์ต๋๋ค:
.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์ ํ ๋นํ ์ ์์
ES2015 ์ด์ ์๋, JavaScript๋ ํด๋์ค ๋์ ์์ฑ์ ํจ์๋ฅผ ์ฌ์ฉํ์ต๋๋ค. ์ปดํ์ผ๋ฌ๋ ์ด๋ฌํ ํจํด์ ์ง์ํ๋ฉฐ ์์ฑ์ ํจ์๋ฅผ ES2015 ํด๋์ค์ ๋์ผํ ๊ฒ์ผ๋ก ์ดํดํฉ๋๋ค. ์์ ์ค๋ช ํ ํ๋กํผํฐ ์ถ๋ก ๊ท์น ๋ํ ์ ํํ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์์ฉํฉ๋๋ค.
function C() {
this.constructorOnly = 0
this.constructorUnknown = undefined
}
C.prototype.method = function() {
this.constructorOnly = false // ์ค๋ฅ
this.constructorUnknown = "plunkbat" // ์ฑ๊ณต, ํ์
์ string | undefined๊ฐ ๋จ
}
.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
.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");
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
ํ์
์
๋๋ค.
์๋ฅผ ๋ค์ด, 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์ ์ง์ ๋์ง ์์ ํ์ ์ธ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก 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 ํ์
์ ํ ๋นํ ์ ์์
์ ๋ค๋ฆญ ํจ์์ ํธ์ถ์ ์ธ์๋ฅผ ์ฌ์ฉํด ํ์
๋งค๊ฐ๋ณ์๋ฅผ ์ถ๋ก ํฉ๋๋ค. ๋๋๋ก ์ด ๊ณผ์ ์ ์ถ๋ก ์์ค๊ฐ ๋ถ์กฑํ์ฌ ์ด๋ ํ ํ์
๋ ์ถ๋ก ํ์ง ๋ชปํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค; ์ด๋ฌํ ๊ฒฝ์ฐ, ๋งค๊ฐ๋ณ์ ํ์
์ ๊ธฐ๋ณธ์ ์ผ๋ก any
์
๋๋ค. ์๋ฅผ ๋ค์ด:
var p = new Promise((resolve, reject) => { reject() });
p; // Promise<any>;
์๋์ ๊ตฌ์ฑ์ JavaScript ํ์ผ์์ JSDoc ์ฃผ์์ ์ฌ์ฉํ์ฌ ํ์ ์ ๋ณด๋ฅผ ์ ๊ณตํ ๋ ์ง์๋๋ ๋ชฉ๋ก์ ๋๋ค.
์๋์ ๋ช
์๋์ง ์์ ํ๊ทธ(@async
๋ฑ)๋ ์์ง ์ง์๋์ง ์๋๋ค๋ ์ ์ ์ ์ํ์ธ์.
@type
@param
(๋๋@arg
๋๋@argument
)@returns
(๋๋@return
)@typedef
@callback
@template
@class
(๋๋@constructor
)@this
@extends
(๋๋@augments
)@enum
๋๋ถ๋ถ์ ํ๊ทธ์ ์๋ฏธ๋ usejsdoc.org์์ ์ค๋ช ํ๋ ํ๊ทธ์ ์๋ฏธ์ ๊ฐ์ต๋๋ค. ์๋์ ์ฝ๋๋ ์ฐจ์ด์ ์ ์ค๋ช ํ๊ณ ๊ฐ ํ๊ทธ์ ์ฌ์ฉ ์์๋ฅผ ์ค๋ช ํฉ๋๋ค.
"@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;
TypeScript๋ ํด๋ก์ ์ ์บ์คํธ(cast) ๊ตฌ๋ฌธ์ ์ฐจ์ฉํฉ๋๋ค.
์ด๋ ๊ดํธํ๋ ํํ์ ์์ @type
ํ๊ทธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ค๋ฅธ ํ์
์ผ๋ก์ ์บ์คํธ๋ฅผ ๊ฐ๋ฅ์ผ ํฉ๋๋ค.
/**
* @type {number | string}
*/
var numberOrString = Math.random() < 0.5 ? "hello" : 100;
var typeAssertedNumber = /** @type {number} */ (numberOrString)
ํ์ 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
์ @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
๋ฅผ ์ฌ์ฉํด ๋ณต์กํ ํ์
์ ์ ์ํ ์ ์์ต๋๋ค.
@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 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) {
// ????
}
์ปดํ์ผ๋ฌ๋ 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 {HTMLElement}
* @param {*} e
*/
function callbackForLater(e) {
this.clientHeight = parseInt(e) // ์ ๋์ด์ผ ํจ!
}
JavaScript ํด๋์ค์ ์ ๋ค๋ฆญ ๊ธฐ์ด ํด๋์ค๋ฅผ ํ์ฅํ ๋, ๋งค๊ฐ๋ณ์๊ฐ ์ด๋ค ํ์
์ด ๋์ด์ผ ํ๋์ง ์ง์ ํ ๊ณณ์ด ์์ต๋๋ค. @extends
ํ๊ทธ๋ ํด๋น ๋งค๊ฐ๋ณ์ ํ์
์ ๋ํ ์์น๋ฅผ ์ ๊ณตํฉ๋๋ค:
/**
* @template T
* @extends {Set<T>}
*/
class SortableSet extends Set {
// ...
}
@extends
๋ ํด๋์ค์์๋ง ์๋ํ๋ค๋ ์ ์ ์์๋์ธ์. ํ์ฌ๋ก์๋, ์์ฑ์ ํจ์๊ฐ ํด๋์ค๋ฅผ ํ์ฅํ๋ ๋ฐฉ๋ฒ์ ์์ต๋๋ค.
@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,
}
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();
}
์์ฑ์ ํจ์์ฒ๋ผ, ๊ฐ ๊ณต๊ฐ(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 ์ผ ๊ฒ์
๋๋ค.