Tslint: no-unused-variable TypeError: null์˜ ์†์„ฑ '1'์„ ์ฝ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2018๋…„ 05์›” 17์ผ  ยท  14์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: palantir/tslint

๋ฒ„๊ทธ ์‹ ๊ณ 

  • __TSLint ๋ฒ„์ „__: 5.10.0
  • __TypeScript ๋ฒ„์ „__: 2.8.1
  • ____๋ฅผ ํ†ตํ•ด TSLint ์‹คํ–‰ํ•˜๊ธฐ: CLI

๋ฆฐํŠธ๋˜๋Š” TypeScript ์ฝ”๋“œ

import { A, B, C } from './file';

console.log('No imports used');

export const D = 4;

tslint.json ๊ตฌ์„ฑ:

{
  "rules": {
    "no-unused-variable": [true, {"ignore-pattern": "^_"}]
  }
}

์‹ค์ œ ํ–‰๋™

The 'no-unused-variable' rule threw an error in '/Users/andrew.mitchell/Documents/Projects/test/test.ts':
TypeError: Cannot read property '1' of null
    at walk (/Users/andrew.mitchell/Documents/test/node_modules/tslint/lib/rules/noUnusedVariableRule.js:105:54)
    at Rule.AbstractRule.applyWithFunction (/Users/andrew.mitchell/Documents/test/node_modules/tslint/lib/language/rule/abstractRule.js:39:9)
    at Rule.applyWithProgram (/Users/andrew.mitchell/Documents/test/node_modules/tslint/lib/rules/noUnusedVariableRule.js:32:21)
    at Linter.applyRule (/Users/andrew.mitchell/Documents/test/node_modules/tslint/lib/linter.js:194:29)
    at /Users/andrew.mitchell/Documents/test/node_modules/tslint/lib/linter.js:139:85
    at Object.flatMap (/Users/andrew.mitchell/Documents/test/node_modules/tslint/lib/utils.js:151:29)
    at Linter.getAllFailures (/Users/andrew.mitchell/Documents/test/node_modules/tslint/lib/linter.js:139:32)
    at Linter.lint (/Users/andrew.mitchell/Documents/test/node_modules/tslint/lib/linter.js:99:33)
    at /Users/andrew.mitchell/Documents/test/node_modules/tslint/lib/runner.js:209:32
    at step (/Users/andrew.mitchell/Documents/test/node_modules/tslint/node_modules/tslib/tslib.js:133:27)

์˜ˆ์ƒ๋˜๋Š” ํ–‰๋™

๊ทœ์น™์€ 1ํ–‰์— ๋Œ€ํ•ด All imports in import declaration are unused. ๋ฅผ ๊ฒฝ๊ณ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ failure ๋ฉ”์‹œ์ง€๊ฐ€ ์ •๊ทœ์‹์—์„œ ์ฐพ์„ ๋ณ€์ˆ˜ ์ด๋ฆ„์ด ์—†๋Š” All imports in import declaration are unused. ์ด๊ธฐ ๋•Œ๋ฌธ์— noUnusedVariableRule.ts#L123 ์— ์˜ํ•ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ทœ์น™์€ ignore-pattern ์˜ต์…˜์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ํ™•์ธํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

Fixed Bug

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

noUnusedLocals ๋ฐ noUnusedParameters ๋ฅผ compilerOptions ๊ฒƒ์€ tslint์˜ no-unused-variable ์™€ ์™„์ „ํžˆ ๋™์ผํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ๋กœ์„œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ๋ณ€์ˆ˜๊ฐ€ ๋นŒ๋“œ๋ฅผ ์ค‘๋‹จ์‹œํ‚ค๊ฑฐ๋‚˜ ๋ˆˆ์— ๋„์ง€ ์•Š๊ฒŒ ์œ ์ง€๋˜๋ฉฐ ๋” ์ด์ƒ ๊ฒฝ๊ณ  ๋ชจ๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค ๐Ÿ˜ž

๋ชจ๋“  14 ๋Œ“๊ธ€

@hotforfeature๋ฅผ ์ž˜ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. https://github.com/palantir/tslint/pull/3919 ์—์„œ ์ด ๋ฌธ์ œ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ์•…ํ™”์‹œํ‚ฌ TS 2.9์˜ ์ผ๋ถ€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๊ณผ ๊ด€๋ จ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋‚ด PR์€ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜์ง€๋งŒ ์–ธ๊ธ‰ํ•œ ๊ฒฝ์šฐ ignorePattern ๋ฅผ ๋ฌด์‹œํ•˜๋Š” ๊ฒƒ์€ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ ๋‹น์žฅ import autofixs๋ฅผ ์œ„ํ•ด ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ณต์žกํ•œ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค./

์ด ๊ทœ์น™์„ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„์•ผ ํ•˜๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. tsc๋Š” ์ด์ œ ๊ฒฝ๊ณ ๋ฅผ ๋ฌด์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๊ณ  IDE๋ฅผ ํ†ตํ•ด ๊ฒฝ๊ณ ์— ๋Œ€ํ•œ ์ž๋™ ์ˆ˜์ •์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋ณผ ์ˆ˜ ์žˆ๋Š” ํ•œ, ์ด ๊ทœ์น™์˜ ์ฃผ์š” ์ด์ ์€ ignore-pattern ์ด์ง€๋งŒ, ์ด์ œ ๊ทœ์น™์ด tsc ์ง„๋‹จ์— ์˜์กดํ•˜๋„๋ก ์ž‘์„ฑ๋œ ๋ฐฉ์‹์œผ๋กœ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. TSLint๋Š” ๋˜ํ•œ ํŠน์ • ํŒŒ์ผ์—์„œ ๊ทœ์น™์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จํ•˜์—ฌ tsc๋ณด๋‹ค ์•ฝ๊ฐ„ ๋” ์œ ์—ฐํ•ฉ๋‹ˆ๋‹ค. @suchanlee ์ด ๋ชจ๋“ 

์ด ๊ทœ์น™์˜ ์ฃผ์š” ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” lintingํ•  ๋•Œ git hook์—์„œ ์ปค๋ฐ‹ ์‹œ ๋ฌธ์ œ๋ฅผ ์ž๋™ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ tsc๊ฐ€ IDE ํ†ตํ•ฉ์„ ํ†ตํ•ด ๋ฌด์–ธ๊ฐ€๋ฅผ ์ œ๊ณตํ•˜๋”๋ผ๋„ ์—ฌ๊ธฐ์—๋Š” ์—ฌ์ „ํžˆ ํฐ ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@JKillian ์ œ ์ƒ๊ฐ์—๋Š” ์—ฌ๋Ÿฌ ๋ฒ„์ „์˜ Typescript์— ๋Œ€ํ•œ TSLint์˜ ์ง€์›๊ณผ Typescript ๋™์ž‘์˜ ์ง€์†์ ์ธ ๋ณ€๊ฒฝ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๊ทœ์น™์ด ์ ์  ๋” ๋น„์‹ธ์ง€๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Typescript๊ฐ€ ์ด ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋Š” ์ชฝ์œผ๋กœ ๊ธฐ์šธ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด์ „ ๋ฒ„์ „์˜ TS์—์„œ๋Š” ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์‚ญ์ œํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ TS์—์„œ ํ˜„์žฌ TSLint ์›Œํฌํ”Œ๋กœ๋ฅผ ๋” ์ž˜ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๊ณ  TS ๋‹ด๋‹น์ž์™€ ํ˜‘๋ ฅํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” @suchanlee ์˜ ์ œ์•ˆ์„ ๋‘ ๋ฒˆ์งธ๋กœ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ทœ์น™์€ ๋ฌธ์ œ์—์„œ ๋งŽ์ด ๋‚˜์˜ค๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ตœ๊ทผ TS ๋ฒ„์ „์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ์ ์ ˆํ•˜๊ฒŒ ๊ฒฝ๊ณ ํ•œ๋‹ค๋Š” ์ ์„ ๊ณ ๋ คํ•˜๋ฉด ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค. ๋‹จ๊ณ„์ ์œผ๋กœ ์—†์• ์ž!

@hotforfeature - ์‚ฌ์šฉ

์–ธ์ œ๋‚˜์ฒ˜๋Ÿผ ๋ˆ„๊ตฌ๋“ ์ง€ ๊ทœ์น™์˜ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ์™ธ๋ถ€ ํŒจํ‚ค์ง€๋กœ ์˜ฎ๊ธฐ๊ณ  ๊ณ„์† ์‚ฌ์šฉ/๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

๊ฐ€์น˜ ์žˆ๋Š” ์ผ:

{
  "compilerOptions":  {
    "noUnusedLocals": true,
    "noUnusedParameters": true,
  }
}

tsconfig ์—์„œ ์œ„์˜ ๋‚ด์šฉ์„ ์‚ฌ์šฉํ•˜๋ฉด no-unused-variable ๋ฆฐํŠธ ๊ทœ์น™์„ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

no-unused-variable ๋Š” ์ด์ œ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ ์œ„์˜ compilerOptions ๋Š” ์ด์ œ ๊ณต์‹ ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค.

noUnusedLocals ๋ฐ noUnusedParameters ๋ฅผ compilerOptions ๊ฒƒ์€ tslint์˜ no-unused-variable ์™€ ์™„์ „ํžˆ ๋™์ผํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ๋กœ์„œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ๋ณ€์ˆ˜๊ฐ€ ๋นŒ๋“œ๋ฅผ ์ค‘๋‹จ์‹œํ‚ค๊ฑฐ๋‚˜ ๋ˆˆ์— ๋„์ง€ ์•Š๊ฒŒ ์œ ์ง€๋˜๋ฉฐ ๋” ์ด์ƒ ๊ฒฝ๊ณ  ๋ชจ๋“œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค ๐Ÿ˜ž

@giladgray , @killtheliterate ๋Š” ๋‹ค์Œ๊ณผ

tsconfig์—์„œ ์œ„์˜ ์‚ฌํ•ญ์„ ์‚ฌ์šฉํ•˜๋ฉด no-unused-variable ๋ฆฐํŠธ ๊ทœ์น™์„ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@kachkaev๊ฐ€ ์“ด ๊ฒƒ์ฒ˜๋Ÿผ ์ด ๊ทœ์น™์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

noUnusedLocals ๋ฐ noUnusedParameters ๋ฅผ compilerOptions ๊ฒƒ์€ tslint์˜ no-unused-variable ์™€ ์™„์ „ํžˆ ๋™์ผํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ์ƒ์„ฑ๋œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์ˆ˜๋™์œผ๋กœ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๊ฐ€ ์ด ๊ทœ์น™์„ ๋”ฐ๋ฅด๊ธฐ๋ฅผ ์›ํ•˜์ง€๋งŒ ์ฝ”๋“œ ์ƒ์„ฑ๊ธฐ๋ฅผ ์—„์ฒญ๋‚˜๊ฒŒ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์ƒ์„ฑ๋œ ์ฝ”๋“œ(๋˜๋Š” ์ ์–ด๋„ ์ƒ์„ฑ๋œ ์ฝ”๋“œ์˜ ์ผ๋ถ€ ์„น์…˜์—์„œ)์—์„œ ์ด ๊ทœ์น™์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. TypeScript ์ปดํŒŒ์ผ๋Ÿฌ ์˜ต์…˜์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค ๐Ÿ˜ž

์ตœ์†Œํ•œ ์ด ์ง€์› ์ค‘๋‹จ์€ TSLint ์›น์‚ฌ์ดํŠธ ์— ๋ฌธ์„œํ™”๋˜์–ด์•ผ ํ•˜์ง€๋งŒ ์ด ์ง€์› ์ค‘๋‹จ์ด ์‹œ๊ธฐ์ƒ์กฐ์˜€๋‹ค๋Š” ๋ฐ ๊ฐ•๋ ฅํžˆ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์žฌ๊ฒ€ํ† ํ•  ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ธฐ๋ถ€๊ฐ€ ํ—ˆ์šฉ๋ฉ๋‹ˆ๊นŒ?

์ด ๋น„์ถ”์ฒœ์€ ์šฐ์Šค๊ฝ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ ํ”Œ๋ž˜๊ทธ๋Š” TERRIBLE ๋Œ€์ฒดํ’ˆ์ž…๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ๋นŒ๋“œ๋ฅผ ๊นจ๊ณ  ์Šค์Šค๋กœ ๊ณ ์น  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์‚ฌ๋žŒ๋“ค์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ•ฉ๋ฆฌ์ ์ธ ํ•ด๊ฒฐ์ฑ…์ž…๋‹ˆ๊นŒ? ignore-pattern ์˜ต์…˜์ด ์ง€๊ธˆ ์ž‘๋™ํ•˜๊ธฐ ๋„ˆ๋ฌด ์–ด๋ ต๋‹ค๋ฉด ๋Œ€์‹  ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

๐Ÿ‘‹ ์—ฌ๋Ÿฌ๋ถ„ - ์ด๊ฒƒ์„ https://github.com/palantir/tslint/issues/4232์— ์—ฐ๊ฒฐํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค no-unused-variable ๋Œ€ํ•œ ์ถฉ๋ถ„ํ•œ ๋Œ€์ฒดํ’ˆ์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์€ ์ž˜ ์ดํ•ด๋˜๊ณ  ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทœ์น™์˜ ์›๋ž˜ ๊ตฌํ˜„์€ ๋‹ค๋ฅธ TS ๋„๊ตฌ์™€ ์ž˜ ์ž‘๋™ํ•˜์ง€ ์•Š์•„ ๋น„ํ™œ์„ฑํ™”ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. #4232๋Š” ๋‹ค์‹œ ํ™œ์„ฑํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๋Š” ๊ณผ์ •์„ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ๋™์•ˆ tsc --noEmit --noUnusedLocals --noUnusedParameters ์™€ ๊ฐ™์€ ๊ฒƒ์„ ๋ณ„๋„์˜ ๋„๊ตฌ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ด์žฅ ์ˆ˜ํ‘œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ, ๊ตฌ์„ฑ ๊ฐ€๋Šฅํ•œ no-unused-variables ๋งŒํผ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

#4100 ๋ฐ #4232์—์„œ ๊ณ„์† ํ† ๋ก 

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰