μλ λ€μ,
μ΄κ²μ΄ λ¬Έμ μΈμ§ λμμΈ κ²°μ μΈμ§ νμ€νμ§ μμ§λ§ no-inferrebale-types
λ° typedef
κ·μΉ μ¬μ΄μ μΆ©λμ λ³Ό μ μμ΅λλ€.
μ .
function fn(): void {
for (let i = 0; i < 100; i++) {
console.log(i);
}
}
https://github.com/palantir/tslint/blob/master/docs/sample.tslint.json μ μ€λν«:
"typedef": [true, ...],
"no-inferrable-types": true,
μ΄ λ κ°μ§ κ·μΉμ μΌλ©΄ λ€μκ³Ό κ°μ κ²°κ³Όκ° λνλ©λλ€.
error (typedef) test.ts[2, 12]: expected variable-declaration: 'i' to have a typedef
i
λ³μμ μ ν μ£Όμ number
μ μΆκ°νλ©΄ μ°¨λ‘λ‘ λ€μ μ€λ₯κ° λ°μν©λλ€.
error (no-inferrable-types) test.ts[2, 14]: LHS type (number) inferred by RHS expression, remove type annotation
μ΄ λ κ°μ§ κ·μΉμ ν¨κ» μ¬μ©ν μ μλ λ°©λ²μ΄ μμ΅λκΉ?
μλ₯Ό λ€μ΄, κΈ°λ³Έ μ ν(κ·μΉ λ¬Έμμμ number
, boolean
λλ string
)μΌλ‘ μ§μ μ μΈλ μΆλ‘ κ°λ₯ν λ³μλ₯Ό κ°κ³ μΆμ§λ§ λ€λ₯Έ ννΈμΌλ‘λ κΈ°λ³Έμ΄ μλ μ νμ λν typedefλ₯Ό κ°μ μ€νν©λλ€.
κ°μ¬ ν΄μ,
μν.
μ μ‘μμ΅λλ€. 미리 μλ €μ£Όμ
μ κ°μ¬ν©λλ€. no-inferrable-types
κ·μΉμ΄ typedef
κ·μΉκ³Ό μΆ©λν μ μλ€λ μκ° μμ΄ no-inferrable-types κ·μΉμ μΆκ°νμ΅λλ€. μ§κΈμ λ μ€ νλλ₯Ό λκ±°λ typedef
κ·μΉμ μΌλΆ μ΅μ
λ§ μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.
μ₯κΈ°μ μΌλ‘ no-inferrable-types
λ₯Ό typedef
κ·μΉμ ν΅ν©νκ±°λ μ΅μν TSLintκ° λ κ·μΉμ λͺ¨λ μ¬μ©νλ κ²κ³Ό κ°μ΄ μΆ©λνλ ꡬμ±μ κ°μ§νλλ‘ ν κ²μ
λλ€.
λλ κ°μ λ¬Έμ μ μ§λ©΄ ν΄μλ€.
μ§κΈμ μΆλ‘ ν μ μλ μ νμ ν΄μ νμ΅λλ€.
μ, μ¬κΈ°μμλ λ§μ°¬κ°μ§μ
λλ€. λ κ·μΉμ΄ 곡쑴ν μ μλ κΈ°λ₯μ κ°κ³ μΆμ΅λλ€.
λ³μμ μ νμ μ μΆν μ μλ κ²½μ° typedef κ·μΉμ΄ μμλλ κ²μ μνμ§ μμ΅λλ€.
μ¦, "μΆλ‘ ν μ μλ μ ν"μ΄ "typedef"λ³΄λ€ μ°μ ν΄μΌ ν©λλ€.
+1
let id: number = 0;
for (let job: string of NAMES_PROFFESSIONS) {
/** some code */
id++;
}
(no-inferrable-types) RHS μμΌλ‘ μ μΆλ LHS μ ν(μ«μ), μ ν μ£Όμ μ κ±°
+1
"μΆλ‘ κ°λ₯ν" μ νμ λν μ μμ μμ±μ ν λΉμ΄ ν¬ν¨λμ΄ μμ΅λκΉ?
// BAD (this hurts my eyes to read)
let labels: Map<string, string> = new Map<string, string>();
// GOOD (type is obvious)
let labels = new Map<string, string>();
νμ§λ§ λν...
// BAD (in a diff, it's not obvious what this type is)
let labels = this.buildLabels();
// GOOD
let labels: Map<string, string> = this.buildLabels();
μ, μνν©λλ€. λ΄ μ½λλ₯Ό λ¨μννκ³ μ§μ μ΄κΈ°νλ λ³μμ λν μ ν μ μΈμ μ¬μ©νμ§ μμΌλ €λ©΄ μ격νκ² μ΄ μμ μ μνν μ μμΌλ©° λ€μκ³Ό κ°μ κ²°κ³Όκ° λ°μν©λλ€.
let x = 2;
let y;
let z: number;
x = 1;
y = 1;
z = 1;
x = 's'; // Type 'string' is not assignable to type 'number'
y = 's'; // It's OK
z = 's'; // Type 'string' is not assignable to type 'number'
μ΄κΈ°νλ λ³μμ λν΄μλ§ μ ν μ μΈμ 건λλ°λλ‘ νμ©νλ κ²μ λ§€μ° μ μ©ν μ΅μ μΌ μ μμ΅λλ€.
... κ·Έλ¦¬κ³ @pgonzal μ΄ λ§νλ―μ΄ μμ μ νμλ§ ν΄λΉλλ κ²μ μλλλ€!
μ΄κ² λ΄, λμ°ν΄
const onChange: () => void = () => this.update();
:+1: μ΄μμ μΌλ‘λ (imo) "μ νμ΄ μ μΆ κ°λ₯ν κ²½μ°κ° μλλ©΄ νμ typedefκ° νμν©λλ€"λΌκ³ λ§νκ³ μΆμ΅λλ€. μ§κΈμ λΆκ°λ₯νλ€κ³ μκ°ν©λλ€.
λλ μ΄κ²μ λΆλͺν λ΄ κ²½μ°μ λμμ΄λλ ignore-params
νλκ·Έλ₯Ό λ§λ€μμ΅λλ€. μ½κ² μ μΆν μ μλ κ²½μ°μλ λͺ¨λ λ©μλ/ν¨μ 맀κ°λ³μμ λν΄ typedefλ₯Ό κ°μ μ μ©νκ³ μΆμ΅λλ€.
μ¬μ©ν΄ λ³΄λ €λ©΄ PR: #1190μ μ°Έμ‘°νμΈμ.
μλ³Έ λ¬Έμ κ° μ μΆλ μ§ μ€λλμμ΅λλ€. μ΄ μμ μμ κΆμ₯ μ΅μ
μ no-inferrable-types
λ₯Ό λΉνμ±ννκ³ λͺ¨λ νλͺ©μ μ νμ ν¬ν¨νλ κ²μ
λκΉ? no-inferrable-types
λ° typedef
λ₯Ό λͺ¨λ μλνκ³ νμ±ννκ³ κ²°ν©νλ λ€λ₯Έ λͺ¨λ κ²μ ν΄νΉμ²λΌ 보μ΄λ©° λ§μ 무μλ―Έν κ²½κ³ λ₯Ό μ΄λν©λλ€. κ°κΉμ΄ μμΌ λ΄μ λ λμ μ루μ
μ κΈ°λν©λλ€.
@corydeppen μμ @englercj μ μμ λν΄ 8κ°μ μμ§μκ°λ½μ μΉμΌμΈμλλ€. κ·νμ "ν΄νΉμ²λΌ 보μ
λλ€" λκΈμμ "κ²°ν©"μ΄ λ¬΄μμ μλ―Ένλμ§ λͺ
ννμ§ μμ΅λλ€. " tslint.json
μμ ν¨κ» μ¬μ©"μ μλ―Ένλ€λ©΄ κ·Έλ μ΅λλ€. νμ§λ§ typedef
μ λν optional-inferrable-types
μΈμλ₯Ό "κ²°ν©"νλ κ²μ νλ₯ν κ²μ
λλ€(μ μ΄λ μ°λ¦¬ μ€ 9λͺ
μκ²λ).
μ΄μ λν μ λ°μ΄νΈλ₯Ό λ°μ μ μμ΅λκΉ?
μ΄κ²μ μ²λ¦¬νλ κ°μ₯ μ’μ λ°©λ²μ no-inferrable-types
λ₯Ό λ μ΄μ μ¬μ©νμ§ μκ³ $#$ typedef
initialized
μ΅μ
κ°μ²΄λ₯Ό μ λ¬νμ¬ νΉμ ν¨ν΄μ λ°λΌ μ νμ μΆλ‘ ν μ μλ κ²½μ° μ ν μ μμ λΆμ‘±μ 무μνλ κ²μ
λλ€. initialized primitives
, call signatures
λ° κ°λ°μλ‘μ μ°λ¦¬μ μꡬλ₯Ό μΆ©μ‘±μν¬ κΈ°ν ν¨ν΄.
λμκ² μ΄κ²μ λ μλ―Έκ° μμ΅λλ€. μλνλ©΄ κ·Έκ²μ΄ ν¨μμ μ νμ΄ λ¬΄μμΈμ§ μλ €μ£Όλ κ²μ΄ μλ€λ©΄ νμ typedefκ° μμ΄μΌ νκΈ° λλ¬Έμ
λλ€. μλ₯Ό λ€μ΄ call signatures
κ° μλ ν΄λμ€μμ μ΄κΈ°νλ properties
κ° μΆλ‘ κ°λ₯ν μ νμ κ°μ§κΈ°λ₯Ό μνκΈ° λλ¬Έμ κ΅¬μ± κ°λ₯ν©λλ€.
λκ΅°κ°κ° μ΄ λ¬Έμ λ₯Ό ν΄κ²°ν μ μλ€λ©΄ μ’μ κ²μ λλ€. κ·ΈλκΉμ§ μ°λ¦¬λ "μ½μ μ μλ νμ μ μΈμ΄ μΆ©λΆνμ§ μμ"κ³Ό "λ무 λ§μ νμ μ μΈμΌλ‘ 볡μ‘ν¨" μ€μμ μ νν΄μΌ ν©λλ€.
μ΄ λ¬Έμ λ 2015λ 10μ 3μΌλΆν° 곡κ°λμμ΅λλ€. κ·Έ μ΄νλ‘ μ ν¬ νμ λ무 λ§μ μ ν μ μΈμΌλ‘ μΈν΄ μ΄μμ ν μ½ 2000κ°μ TypeScript μμ€ νμΌμ μμ±νμ΅λλ€.
typedef
ꡬμ±μ μλ½ν©λλ€. λ°λΌμ μ νμ΄ μ μΆ κ°λ₯ν κ²½μ° μ ν μ μλ₯Ό 무μνλ λ λ€λ₯Έ ꡬμ±μΌ μ μμ΅λλ€.
μ΄κΈ°νλμ§ μλ κ³³μ μ λ ₯νλ©΄ λ©λλ€.
λ¬Έμ λ₯Ό μ΄λ»κ² μ²λ¦¬ν΄μΌ νλμ§μ λν λͺ νν ν©μκ° μ΄λ£¨μ΄μ§μ§ μμ μ§μ μ΄ μλ κ²μΌλ‘ 보μ λλ€. μ£Όμ μμ: https://github.com/theia-ide/theia/issues/356#issuecomment -319350833
λλ μ°λ¦¬ λͺ¨λκ° μ΄λ€ ν΄κ²°μ± μ΄λ μλ κ·Έλλ‘ λλ κ²λ³΄λ€ λ«λ€λ λ° λμνλ€κ³ μκ°ν©λλ€. μ΄ λ¬Έμ μ κ΄λ ¨νμ¬ νμ μ μ§μ λν λ³κ²½ μ¬νμ΄ μ’λ€κ³ μκ°νμλ©΄ μ΄ λκΈμ π λΆνν©λλ€. μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ PRμ μμ±ν λ§νΌ μ§μμ΄ μλ€λ©΄ μ°λ¦¬ λͺ¨λλ₯Ό λμμ£ΌμΈμ β€οΈ .
λ€μκ³Ό κ°μ κ²½μ° PRμ μλ½ν©λλ€.
typedef
μ μ΅μ
μ μΆκ°νμ¬ no-inferrable-types
μμ μ νμ μ 곡νμ§ λ§λΌκ³ νλ κ²½μ°λ₯Ό 무μν μ μμ΅λλ€.typedefλ ꡬμ±μ νμ©ν©λλ€. λ°λΌμ μ νμ΄ μ μΆ κ°λ₯ν κ²½μ° μ ν μ μλ₯Ό 무μνκΈ° μν λ λ€λ₯Έ ꡬμ±μΌ μ μμ΅λλ€. μ¦, 'μ΄κΈ°νλμ§ μμ μμΉμ μ λ ₯νμμμ€.'
typedef
κ·μΉμ μ½λλ² μ΄μ€μ λͺ
μμ μ ν μ μλ₯Ό κ°κ³ μΆμ΄νλ μ¬λλ€μ μν κ²μ
λλ€. μμ λμμ΄ "μ΄κΈ°νλμ§ μμ λͺ¨λ μμΉμ μ
λ ₯"νλλ‘ νλ €λ©΄ typedef
λ₯Ό λΉνμ±ννκ³ TypeScript μ»΄νμΌλ¬ μ΅μ
μΌλ‘ noImplictAny
λ₯Ό νμ±ννλ κ²μ΄ μ’μ΅λλ€.
λ€μ μ€λν«κ³Ό κ°μ΄ μ΄κΈ°νλ μΌλΆ νλͺ©μ μ΄μ¨λ typedefκ° νμν κΉλ€λ‘μ΄ κ²½μ°λ μμ΅λλ€.
interface Literal {
field: "value"
}
const literal0 = {
field: "value",
};
const literal1: Literal = {
field: "value",
};
const func = (obj: Literal) => { };
func(literal0); // Error! Type 'string' is not assignable to type '"value"'.
func(literal1);
λν μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ λμ no-unnecessary-type-annotation
(https://github.com/ajafff/tslint-consistent-codestyle/blob/)μ κ°μ νλ₯ν νμ¬ κ·μΉμ΄ μμ μ μμμ μΈκΈνκ³ μΆμμ΅λλ€. μλ₯Ό λ€μ΄ master/docs/no-unnecessary-type-annotation.md). μνλ λμμ μ 곡νλ λ€λ₯Έ νμ¬ κ·μΉμ μκ³ μλ μ¬λμ΄ μλ κ²½μ° μ¬κΈ°μ κ²μν΄ μ£Όμλ©΄ 곡μμ μΌλ‘ κΆμ₯νκ±°λ νλΉν κ²½μ° ν΅μ¬μ μ±νν μ μμ΅λλ€.
@JKillian μΆμ² κ°μ¬ν©λλ€. μ€μ λ‘ μ κ° μνλ κ² κ°μμ. any
μ νμ νΌνλ κ²μ λν μμ£Ό μ’μ κ²μλ¬Όμ΄ μμ΅λλ€. "naked any"λ₯Ό μ¬μ©νμ§ λ§κ³ λμ "any interface"λ₯Ό λ§λμμμ€.
μ λν:
interface Literal {
field: "value"
}
const literal0 = {
field: "value",
};
const literal1: Literal = {
field: "value",
};
const func = (obj: Literal) => { };
func(literal0); // Error! Type 'string' is not assignable to type '"value"'.
func(literal1);
λλ μ΄κ²μ΄ μ΄λ»κ² λ°λμ§νμ§ μμ νλμ΄λ κΉλ€λ‘μ΄ κ²½μ°μΈμ§ μ μ μμ΅λλ€. obj
κ°μ΄ value
μΈ $#$ field
$#$ μμ±μ΄ μλμ§ νμΈνκ³ μ μ½ μ‘°κ±΄μ²λΌ 보μ΄λ μμ±μΌλ‘ literal0
λ₯Ό μ΄κΈ°ννλ κ²½μ°μλ , λ€λ₯Έ λ¬Έμμ΄λ‘ μμ ν μ μμ΅λλ€.
μ’μ μ¬μ© μ¬λ‘λ μλμ§λ§ λλΆλΆμ κ²½μ° λ¦¬ν°λ΄μ μ¬μ©νλ κ²½μ° κΈ°λ³Έμ΄ μλ ν΄λΉ 리ν°λ΄μ μν κ²μ λλ€.
λ€μ ꡬμ±μ΄ μμ΅λλ€.
json
"no-inferrable-types": true,
"typedef": [true, "call-signature", "parameter"],
κ·Έλ¦¬κ³ μ΄ μ½λ:
javascript
private static readonly DEVICE_UID: string = 'device_uid';
private static readonly DEVICE_PLATFORM: string = 'browser';
private static readonly AGENT_DEFAULT_ICON = 'http://localhost:3000/icon.png';
λ κ°μ 첫 λ²μ§Έ μ μΈμμ μ€λ₯κ° λ°μνμ§ μλ μ΄μ λ 무μμ λκΉ?
@sandrocsimas ν₯λ―Έλ‘μ§ λ§ μ£Όμ κ° μλ κ² κ°μ΅λλ€. AFAICT ν΄λΉ λ¬Έμ λ μ΄ λ¬Έμ μ κ΄λ ¨μ΄ μμ΅λλ€. λ€λ₯Έ λ¬Έμ λ₯Ό μμνλ κ²μ΄ μ’μ΅λλ€(fwiw!).
@estaub λ€, κ·Έλ κ² νκ² μ΅λλ€. typedef κ·μΉμ΄ μμ΄λ λμΌν λμμ΄ λ°μν©λλ€.
@sandrocsimas λ μ½κΈ° μ μ© μμ±μ΄κ³ μ΄λ¬ν Typescriptλ ν΄λΉ μ νμ 리ν°λ΄λ‘ μ μΆνκΈ° λλ¬Έμ λλ€. κ·Έκ²μ λ¬Έμμ΄λ‘ μ λ ₯νλ©΄ λ¬Έμμ΄μ΄ μμ΄μΌ ν¨μ μλ―Έν©λλ€. λ°λμ ν΄λΉ 리ν°λ΄ κ°μ κ°μ§ νμλ μμΌλ©° κ°μ΄ μ μ μΌλ‘ λ³κ²½λμ΄μλ μ λ©λλ€.
'typedef-except-inferrable' κ·μΉμ΄ μμΌλ©΄ μ’μ κ²μ λλ€.
@JKillian μ΄ λ§νλ―μ΄ @FiretronP75 λ TSCμ noImplicitAny
μ΅μ
μΌ λΏμ
λλ€.
@michaeljota κ°μ¬ν©λλ€. μ»΄νμΌλ¬μ noImplicitAny
μ΅μ
μ΄ μΆλ‘ ν μ μλ μμΈλ₯Ό μ 곡νλ€λ κ²μ λͺ°λμ΅λλ€. κ·Έλλ μ»΄νμΌμ μ€λ¨νλ λμ κ²½κ³ λ₯Ό λ§λλ μ΅μ
κ³Ό tslint μ£Όμ νλκ·Έλ₯Ό κ°λ μ΅μ
μ μν΄ tslintμ μμΌλ©΄ μ’μ κ²μ
λλ€.
μ΄κ²μ΄ μνλ μ΄μ λ₯Ό μμ§λ§ no-unused-variables
λ₯Ό μλ‘ λ€λ©΄ TSCμμ λ€λ£¨λ μ¬μ© μ¬λ‘κ° TSLint νμμ μ§μλμ§ μμ κ²μ΄λΌκ³ μκ°ν©λλ€. λλ κ·Έκ²μ΄ _μ»΄νμΌλ¬ μ€λ₯_μ κ°μ _λ¦°ν° μ€λ₯_κ° μλλΌλ κ²μ μκ³ μμ§λ§ κ²°κ΅ λ λ€ λ λμ μ½λλ₯Ό μμ±νλ κ²μ κ΄ν κ²μ
λλ€. TSC μ€λ₯κ° μλ κ²½μ°μλ μ½λλ₯Ό μ»΄νμΌνκ³ μ€νν μ μλ Webpack λλ Parcelκ³Ό κ°μ μ루μ
μ΄ μλ μμ¦μλ μ΄κ²μ΄ μ€μ λ¬Έμ λ‘ λ³΄μ΄μ§ μμ΅λλ€.
μ΅μ λ²μ μμλ ν΄κ²°λμλμ?
λλ μ΄κ²μ΄ λ‘λ맡μ μμ§ μλ€κ³ μκ°νλ€. TSCμμ noImplicitAny
μ¬μ©μ κ³ λ €ν΄μΌ ν©λλ€.
β οΈ TSLintμ μκ°μ΄ μμ΅λλ€! β οΈ
TSLintλ #4534μ λ°λ₯Έ λλΆλΆμ κΈ°λ₯ μμ²μ λ μ΄μ μλ½νμ§ μμ΅λλ€. ESLint λ‘ TypeScript μ½λλ₯Ό λ¦°νΈνλ μλ‘κ³ λΉλλ λ°©λ²μ typescript-eslint.io λ₯Ό μ°Έμ‘°νμΈμ. β¨
μ¬λ¬λΆκ³Ό ν¨κ» μ¦κ±°μ΄ μ€νμμ±μ΄μμ΅λλ€!
π€ μμ! π TSLintλ λ μ΄μ μ¬μ©λμ§ μμ΅λλ€ π _(#4534)_ κ·Έλ¦¬κ³ typescript-eslint λ‘ μ ν ν΄μΌ ν©λλ€! π€
π μ΄ μ΄μλ λ μ΄μμ λΆνμν ν λ‘ μ λ°©μ§νκΈ° μν΄ μ κ·Έκ³ μμ΅λλ€. κ°μ¬ν©λλ€! π
κ°μ₯ μ μ©ν λκΈ
:+1: μ΄μμ μΌλ‘λ (imo) "μ νμ΄ μ μΆ κ°λ₯ν κ²½μ°κ° μλλ©΄ νμ typedefκ° νμν©λλ€"λΌκ³ λ§νκ³ μΆμ΅λλ€. μ§κΈμ λΆκ°λ₯νλ€κ³ μκ°ν©λλ€.