๊ฒฝ์ฐฐ 24์๐ฎโโ๏ธ
11105 ๋จ์ด TypeScript
๋ง์ง๋ง ๊ฒ์๋ฌผ CLI ๋๊ตฌํ, any ๊ฒฝ์ฐฐ๐ฎโโ๏ธ๋๋ฒ๊น ์ ์งํํ๋ค.์๊ธฐ ํ์ผ์์ ์ค๋ช ํ ๋ฐ์ ๊ฐ์ด devDependencies์ ์ถ๊ฐํ๊ณ ์คํ
npx anycop
ํ๋ฉด ํ๋ก์ ํธ์ ๋ํดany ์ง๋จ์ ํ ์ ์์ต๋๋ค.anycop: https://www.npmjs.com/package/anycop
์ฌ์ ํ๋ค
์ด๊ฒ์ ์ ๋๋ฅผ ์ซ์๋ด๊ธฐ ์ํด ๋ง๋ ๊ฒ์ด ์๋๋ค.any์ ์ฌ์ฉ ์ํฉ์ด ๊ฐ์ํ๋๋ฉด ๊ณผ์ ์ ์ ํ์ ํ๊ณ ํ์ ๊ณต์ ํ ์ ์์ต๋๋ค.์๊ฐ์ด ์์ ๋ ํฅ์ํ ์์ ์ปค๋ฒ ์กฐ์น๋ฅผ ์ทจํ ์ ์๋ค๋ฉด ์ ๋ง ์ข์ ์ผ์ด๋ค.any ๋์ ์ฌ๋ ์๋์์.TypeScript์ ์ด ์ฌ์์ด ์์ผ๋ฉด ํ์ฌ JavaScript ์ํ๊ณ์์ ์ ์ ์ ํ์ ์ ์ฉํ ์ ์์ต๋๋ค.์ด ๋๊ตฌ๋กany์ ๋ ์ข์ ๊ด๊ณ๋ฅผ ๋งบ์ ์ ์๋ค๋ฉด ์ข๊ฒ ๋ค.
๋ณ๊ฒฝ ์ฌํญ
์ง๋๋ฒ ํฌ๊ณ ๋'๋ณ์ ์ ์์any์ถ๋ฆฌ'์ ํ์ ๋์์ง๋ง ํ์ ๋์ฌ ๋ค์any๋ฅผ ๊ฒ์ถํ๊ธฐ ์์ํ๋ค.
๋ณ์ ์ฑ๋ช ์anyํ ์ถ๋ฆฌ
๊ทธ๊ฒ์ ๋ณ์์ ํ์any ์ฃผ์์ ๊ฒ์ถํ ๋ฟ๋ง ์๋๋ผany ์ถ๋ฆฌ๋ ๊ฒ์ถํ๋ค.
function greet(message: any) {
return message
}
// inferred "any" at VariableDeclaration
const message = greet('hello')
ํจ์ ๋งค๊ฐ ๋ณ์์anyํ ์ถ๋ฆฌ
ํ๋ผ๋ฏธํฐ์ ํ์any ์ฃผ์์ ๊ฒ์ถํ ์ ์์ ๋ฟ๋ง ์๋๋ผ, ์ธ์ฉ์ ์ ํ ์ ์๊ฐany์ ํด๋นํ๋ ์ํฉ๋ ๊ฒ์ถํ ์ ์๋ค.
// annotation of "any" at ParameterDeclaration (message)
function greet(message: any) {
return message
}
Binding Element์ any ์ถ๋ฆฌ
๊ท์ ์์์์ ์ ๊ฐ๋๋ ์ธ์ฉ์ดany ์ถ๋ฆฌ์ผ ๋๋ ๊ฒ์ถ๋ฉ๋๋ค.
type Props = { a: any, b: any }
// inferred "any" at BindingElement (a & b)
function greet({ a, b }: Props) {
return { a, b }
}
ํจ์์any ๋ฐํ ์ถ๋ฆฌ
๋๋์์ค๋ ํ์์ ํ์any ์ฃผ์์ ๊ฒ์ถํ ์ ์์ ๋ฟ๋ง ์๋๋ผany์ ๋๋์์ค๋ ํ์๋ ๊ฒ์ถํ ์ ์๋ค.
// inferred "any" at FunctionDeclReturn
function greet() {
const message: any = 'hello'
return message
}
arrow ํจ์์any ๋ฐํ ์ถ๋ฆฌ
๋๋์์ค๋ ํ์์ ํ์any ์ฃผ์์ ๊ฒ์ถํ ์ ์์ ๋ฟ๋ง ์๋๋ผany์ ๋๋์์ค๋ ํ์๋ ๊ฒ์ถํ ์ ์๋ค.
// inferred "any" at ArrowFunctionReturn
const abc = (param: string) => {
switch (param) {
case 'a':
return true
case 'b':
return false
case 'c':
return '' as any
}
}
as Expression(as any ๋จ์ธ)
as ๊ฒ์ฌ ํค์๋ ๋จ์ธ.
function greet() {
return 'hello' as any // at AsExpression
}
anycop.config.js
ํ๋ก์ ํธ ๋ฃจํธ ๋๋ ํฐ๋ฆฌ์ ์ค์ anycop.config.js
์ ํตํด ํน์ ํ ์ค์ ์ ํ ์ ์์ต๋๋ค.errorThrethold
๋ ์ค๋ฅ ๋ณด๊ณ ์์ ์๊ณ๊ฐ์
๋๋ค.Type Safe Coverage์ ํฉ๊ณ๊ฐ ์ด๋ณด๋ค ๋ฎ์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.ํตํฉ ๋๊ตฌ ๋ฑ์ ๊ฐ์ ธ์ค๋ ๋ฐ ์ฌ์ฉํ์ญ์์ค.module.exports = {
targetDir: ".",
errorThrethold: 0.2
}
๊ฒ์ฌ ํญ๋ชฉ ์ฆ๊ฐ๋ก ์ธํ ๋ณ๊ฒฝ ์ฌํญ ts.SourceFile
์ts.Node
์ ๋ฃจํธ ๋
ธ๋๋ก ์ด๋ฅผ ๊ธฐ์ ์ผ๋ก ์คํ๋๋ ๊ท์ ํจ์(visit ํจ์)๋ฅผ ์ฌ๊ฒํ ํ๋ค.ts.Node
๋ณด์ ts.SyntaxKind
, ์ด Syntax Kind๋ก ์ฒ๋ฆฌ๋ฅผ ์ ํํฉ๋๋ค.function visit(node: ts.Node) {
switch (node.kind) {
case ts.SyntaxKind.VariableDeclaration:
// ๅคๆฐๅฎฃ่จใงใใใฐ
// ....ๅฆ็
break
case ts.SyntaxKind.Parameter:
// ๅผๆฐใงใใใฐ
// ....ๅฆ็
break
case ts.SyntaxKind.BindingElement:
// BindingElementใงใใใฐ
// ....ๅฆ็
break
case ts.SyntaxKind.FunctionDeclaration:
// ้ขๆฐๅฎฃ่จใงใใใฐ
// ....ๅฆ็
break
case ts.SyntaxKind.ArrowFunction:
// ใขใญใผ้ขๆฐๅฎฃ่จใงใใใฐ
// ....ๅฆ็
break
case ts.SyntaxKind.AsExpression:
// ใขใตใผใทใงใณใงใใใฐ
// ....ๅฆ็
break
}
ts.forEachChild(node, visit)
}
visit(source)
ts.TypeChecker.getReturnTypeOfSignature
'๋ถ์ฃผ์ ํจ์ ๋ฐํํ์ดany์ ๋น ์ก๋๋ฐ...'๋ผ๋ ๊ฒ์ฌ๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.ts.SignatureDeclaration
๋ ํจ์ ์ฑ๋ช
์ด๋ ํ์ดํ ํจ์๋ฅผ ๊ฐ๋ฆฌํจ๋ค.ts.TypeChecker
์ ์๋ getSignatureFromDeclaration
ํจ์์ getReturnTypeOfSignature
ํจ์๋ฅผ ์ด์ฉํ์ฌ flags
ํจ์๋ฅผ ์ป์ ์ ์๋ค.์ด์ ๋ฐ๋ผ ts.TypeFlags.Any
๊ณผ ์ผ์นํ๋์ง Any ์ธ์ง ์ฌ๋ถ๋ฅผ ํ๋จํฉ๋๋ค.// ts.ArrowFunction / ts.FunctionDeclaration ใฏ
// ts.SignatureDeclaration ใฎใตใใฟใคใ
// node: ts.SignatureDeclaration
const signature = checker.getSignatureFromDeclaration(node)
if (signature) {
const { flags } = checker.getReturnTypeOfSignature(signature)
return checkAny(source, node, flags, name)
}
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๊ฒฝ์ฐฐ 24์๐ฎโโ๏ธ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค
https://qiita.com/Takepepe/items/1d61b3314459e81d849c
ํ
์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ
์ธ ๋ฐ๊ฒฌ์ ์ ๋
(Collection and Share based on the CC Protocol.)
module.exports = {
targetDir: ".",
errorThrethold: 0.2
}
ts.SourceFile
์ts.Node
์ ๋ฃจํธ ๋
ธ๋๋ก ์ด๋ฅผ ๊ธฐ์ ์ผ๋ก ์คํ๋๋ ๊ท์ ํจ์(visit ํจ์)๋ฅผ ์ฌ๊ฒํ ํ๋ค.ts.Node
๋ณด์ ts.SyntaxKind
, ์ด Syntax Kind๋ก ์ฒ๋ฆฌ๋ฅผ ์ ํํฉ๋๋ค.function visit(node: ts.Node) {
switch (node.kind) {
case ts.SyntaxKind.VariableDeclaration:
// ๅคๆฐๅฎฃ่จใงใใใฐ
// ....ๅฆ็
break
case ts.SyntaxKind.Parameter:
// ๅผๆฐใงใใใฐ
// ....ๅฆ็
break
case ts.SyntaxKind.BindingElement:
// BindingElementใงใใใฐ
// ....ๅฆ็
break
case ts.SyntaxKind.FunctionDeclaration:
// ้ขๆฐๅฎฃ่จใงใใใฐ
// ....ๅฆ็
break
case ts.SyntaxKind.ArrowFunction:
// ใขใญใผ้ขๆฐๅฎฃ่จใงใใใฐ
// ....ๅฆ็
break
case ts.SyntaxKind.AsExpression:
// ใขใตใผใทใงใณใงใใใฐ
// ....ๅฆ็
break
}
ts.forEachChild(node, visit)
}
visit(source)
ts.TypeChecker.getReturnTypeOfSignature
'๋ถ์ฃผ์ ํจ์ ๋ฐํํ์ดany์ ๋น ์ก๋๋ฐ...'๋ผ๋ ๊ฒ์ฌ๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.ts.SignatureDeclaration
๋ ํจ์ ์ฑ๋ช
์ด๋ ํ์ดํ ํจ์๋ฅผ ๊ฐ๋ฆฌํจ๋ค.ts.TypeChecker
์ ์๋ getSignatureFromDeclaration
ํจ์์ getReturnTypeOfSignature
ํจ์๋ฅผ ์ด์ฉํ์ฌ flags
ํจ์๋ฅผ ์ป์ ์ ์๋ค.์ด์ ๋ฐ๋ผ ts.TypeFlags.Any
๊ณผ ์ผ์นํ๋์ง Any ์ธ์ง ์ฌ๋ถ๋ฅผ ํ๋จํฉ๋๋ค.// ts.ArrowFunction / ts.FunctionDeclaration ใฏ
// ts.SignatureDeclaration ใฎใตใใฟใคใ
// node: ts.SignatureDeclaration
const signature = checker.getSignatureFromDeclaration(node)
if (signature) {
const { flags } = checker.getReturnTypeOfSignature(signature)
return checkAny(source, node, flags, name)
}
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๊ฒฝ์ฐฐ 24์๐ฎโโ๏ธ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค
https://qiita.com/Takepepe/items/1d61b3314459e81d849c
ํ
์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ
์ธ ๋ฐ๊ฒฌ์ ์ ๋
(Collection and Share based on the CC Protocol.)
// ts.ArrowFunction / ts.FunctionDeclaration ใฏ
// ts.SignatureDeclaration ใฎใตใใฟใคใ
// node: ts.SignatureDeclaration
const signature = checker.getSignatureFromDeclaration(node)
if (signature) {
const { flags } = checker.getReturnTypeOfSignature(signature)
return checkAny(source, node, flags, name)
}
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๊ฒฝ์ฐฐ 24์๐ฎโโ๏ธ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://qiita.com/Takepepe/items/1d61b3314459e81d849cํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค