λ€μκ³Ό κ°μ΄ μΈλΆ TypeScript λͺ¨λ μ§ν©μ λ§λ€λ €κ³ ν©λλ€.
// ClassA.ts
export default class ClassA {
public method() { return true; }
}
// ModuleB.ts
import ClassA from './ClassA';
var moduleB = {
ClassA: ClassA
};
export default moduleB;
// ModuleA.ts
import moduleB from './ModuleB';
var moduleA = {
moduleB: moduleB
}
export default moduleA;
μμ΄λμ΄λ μ΄κ²μ΄ μ»΄νμΌλμ΄ λΌμ΄λΈλ¬λ¦¬λ‘ μ 곡λλ€λ κ²μ λλ€. κ³νμ λΌμ΄λΈλ¬λ¦¬ μλΉμκ° λ€μκ³Ό κ°μ΄ ClassA μΈμ€ν΄μ€λ₯Ό μΈμ€ν΄μ€ννλ κ²μ λλ€.
import moduleA from './ModuleA';
var anInstance = moduleA.moduleB.ClassA();
μ΄κ²μ μμλλ JSλ‘ μ»΄νμΌνλ κ²μ²λΌ 보μ΄μ§λ§ μΆκ° μ 보λ₯Ό μ°ΎκΈ° μν΄ κ³ κ΅°λΆν¬νλ μ€λ₯ μ»΄νμΌλ¬ μ€λ₯κ° λ°μν©λλ€.
Using tsc v1.6.2
.../src/ModuleA.ts(3,5): error TS4023: Exported variable 'moduleA' has or is using name 'ClassA' from external module ".../src/ClassA" but cannot be named.
μ¬κΈ° λꡬλ μ§μ΄ λ¬Έμ μ λν΄ λ°ν μ μμ΅λκΉ? λ΄κ°νλ €λ κ²μ΄ μ΄ν΄κ° λλμ?
μ€-μ΄κ²μ΄μ΄ μ§λ¬ΈμνκΈ°μ μ ν©ν μ₯μκ° μλλΌλ©΄. μλ € μ£Όμλ©΄ λ€λ₯Έ 맀체μ κ²μ ν΄ λλ¦¬κ² μ΅λλ€.
FWIWλ μΌλ°μ μΌλ‘ Stack Overflowμμ λ λΉ λ₯Έ λ΅λ³μ μ»μ μ μμ§λ§ μ¬κΈ°μλ νλμ μ νν λ μ§λ¬Έμν©λλ€.
μ¬κΈ°μ λ¬Έμ λ --declaration
νλκ·Έλ₯Ό μ¬μ©νκ³ μμ§λ§ μ»΄νμΌλ¬κ° μμ
μ μν ν μμλ λ°©λ²μ μ 곡νμ§ μμλ€λ κ²μ
λλ€.
ModuleA.d.ts
λ₯Ό λ΄λ³΄λ΄λ €κ³ ν λ μ»΄νμΌλ¬λ λͺ¨λμ λͺ¨μμ λνλ΄λ κ°μ²΄ μ ν 리ν°λ΄ (μ : { moduleB: { classA: *mumble?* } }
)μ μμ±ν΄μΌν©λλ€. κ·Έλ¬λ classA
μ§μ μ°Έμ‘°νλ μ΄λ¦μ΄ λ²μμ μμΌλ―λ‘ "μ΄λ¦μ μ§μ ν μ μμ"μ νμ΄λ©° μ€λ₯κ° μμ΅λλ€.
import
of ClassA
λ₯Ό ModuleA.ts
μ μΆκ°νλ©΄ μ€λ₯κ° μ¬λΌμ§λλ€.
μλ
Ryan-μ‘°μΈ RE μ€ν μ€λ²νλ‘μ μ‘°μΈμ κ°μ¬λ립λλ€- ModuleA
κ°μ Έ μ€κΈ°λ₯Ό μΆκ°νλ©΄ μμλλ‘ μ»΄νμΌμ΄ μ΄λ£¨μ΄μ§λλ€.
μ¬κΈ°μ μ½κ°μ 컨ν
μ€νΈκ° μμ΅λλ€. μ λͺ©νλ μ€μ λ‘ μΈλΆ λͺ¨λμ λν μ μΈμ μμ±νλ κ²μ
λλ€. (μμ§ μ λλ‘ μλνμ§ μλλ€κ³ μκ°νλ λΆλΆμ΄ μμ΅λκΉ? # 5039?)μ΄ κ°μ Έ μ€κΈ°κ° μμ ν νμν μ μμ§λ§ ModuleA
μμ moduleBκ° μ΄λ―Έ λ΄λ³΄λ΄λ κΈ°νΈλ₯Ό κ°μ ΈμμΌνλ κ²μ΄ μ‘°κΈ μ΄μν©λλ€. κ²°κ³Όμ μΌλ‘ ModuleB
μ κ°μ²΄ λ΄λ³΄λ΄κΈ°μ μΆκ° ν λλ§λ€ κ°μ Έ μ€κΈ°λ₯Ό ModuleA
μ§μ μΆκ°ν΄μΌν©λλ€.
import {moduleB} from './moduleB';
import {ClassA} from './ClassA';
λλ ModuleB
(λ κ³³ λͺ¨λμμ ClassA
μ λν κ²½λ‘ μ§μ μ μ€μ΄κΈ° μν΄) :
import {moduleB, ClassA} from './moduleB';
λλ TS μ»΄νμΌλ¬μ λν΄ κ±°μ μμ§ λͺ»ν©λλ€. κ·Έλμ μ κ° λ§νλ κ²μ μμ ν λΉνμ€μ μΌ μ μμ§λ§ μ²μμλ μ»΄νμΌλ¬κ° ModuleB
κ° N κ°μ κΈ°νΈκ°μλ κ°μ²΄λ₯Ό λ΄λ³΄λ΄κ³ μλ€κ³ μΆλ‘ ν μ μλ€κ³ μκ° νμΌλ―λ‘ ModuleA
ν΄λΉ κΈ°νΈκ° νμν©λκΉ? ModuleB
λν κ°μ Έ μ€κΈ° μ λ³΄κ° μ΄λ―Έ μμ΅λλ€. ModuleA
μ¬μ©ν μ μμ΅λκΉ? λλ ClassA
λν κ°μ Έ μ€κΈ°κ° μμ ν ModuleB
λ΄λΆμ μμΌλ―λ‘ λΆκ°λ₯νλ―λ‘ ClassA
λν μ νμ μΆλ‘ ν μμλ λ°©λ²μ΄ μμ΅λλ€ ModuleA
?
μκ°μλ΄μ΄ λ΅λ³ ν΄ μ£Όμ μ λ€μ ν λ² κ°μ¬λ립λλ€. λλ μ§κΈ λ΄ λ¬Έμ λ₯Ό λΆλ₯ νμΌλ―λ‘ μμ λ΄μ©μ μ£Όλ‘ νΈκΈ°μ¬μ λλ€. μλλ₯΄μ§ μμ΅λλ€.
λΉμ μ΄ λ¬΄μ¨ λ§μνλμ§ μ νν λͺ¨λ₯΄κ² μ΅λλ€. μ΄ μ μμμ ModuleA.d.ts
μ (λ) μ΄λ»κ² νμλμ΄μΌν©λκΉ?
μ»΄νμΌλ¬λ μ μΈμ λ΄λ³΄λΌ λ μ¬μ©μ μ½λμ μ‘΄μ¬νμ§ μλ μ’ μμ± (μ¦, import λ¬Έ)μ μΆκ°νμ§ μμ΅λλ€. νμλλ μ€λ₯λ μ»΄νμΌλ¬κ° λ΄ λ³΄λΈ μ μΈμ λν μ ν μ£Όμμ μμ±νλ €κ³ νμ§λ§ ν μ μμμ μλ―Έν©λλ€. μ΄κ²μ λ κ°μ§ μ΄μ μ€ νλλ₯Ό κ°μ§ μ μμ΅λλ€. μ΄λ¦μ μ‘μΈμ€ ν μ μμ΅λλ€. μ¦ νμ¬ λͺ¨λμμ κ°μ Έ μ€μ§ μμκ±°λ μλ μ μΈμ μ¨κΈ°λ μ μΈμ΄ μμ΅λλ€.
λ κ²½μ° λͺ¨λ ν΄κ²° λ°©λ²μ λͺ μ μ μ ν μ£Όμμ μΆκ°νλ κ²μ λλ€. μ ν μ£Όμμ μΆκ°νλ©΄ μΆλ ₯μμ ββκ·Έλλ‘ λ΄λ³΄λ΄μ§λλ€. λ€λ₯Έ μ΅μ μ μ΄λ¦μ μ‘μΈμ€ ν μ μλμ§ νμΈνλ κ²μ λλ€. μ¦, λͺ¨λμ λν κ°μ Έ μ€κΈ°κ° μκ³ λͺ¨λμ κ°μ Έ μ€λ μ¬μ©μμκ² μ΄κ²μ΄ μλ―Ένλ λ°λ₯Ό μ΄ν΄ν©λλ€.
@mhegazyκ° λ§νμ΅λλ€.
μ»΄νμΌλ¬λ μ μΈμ λ΄λ³΄λΌ λ μ¬μ©μ μ½λμ μ‘΄μ¬νμ§ μλ μ’ μμ± (μ¦, import λ¬Έ)μ μΆκ°νμ§ μμ΅λλ€.
λ¬Έμ λ μ½λμ νμ import λ¬Έμ΄ νμνμ§λ μμΌλ©° (λΆλͺ
ν --declarations
μμ΄ μλνκΈ° λλ¬Έμ), κ·Έκ²λ€μ ν¬ν¨νλ©΄ μλλ¬μμ tslint
κ°μ κ²λ€μ΄ "λ―Έμ¬μ© μμ
". μ»΄νμΌλ¬κ° λ΄ λ³΄λΈ μλ° μ€ν¬λ¦½νΈμ μ’
μμ±μ μΆκ°νλ κ²μ μνμ§ μλ μ΄μ λ₯Ό μ μ μμ§λ§ μ μΈμ λ΄λ³΄λμΌλ‘μ¨ μ’
μμ±μ μΆκ°νλ λ° μ΄λ€ λ¬Έμ κ° μμ΅λκΉ?
μ΄ μ μμ μΆμ νλ €λ©΄ μΈμ λ μ§ λ¬Έμ λ₯Ό κΈ°λ‘νμμμ€. ν©λ¦¬μ μΈ κ²μ importsλ μ’ μμ±μ μ μΈμ΄λ©° μ»΄νμΌλ¬λ μ¬μ©μκ° μ§μνμ§ μλ νμ΄λ₯Ό μμ±νμ§ μμμΌν©λλ€.
μ΄κ²μ λ κΉμ κ²°κ³Όλ₯Ό κ°μ Έμ¬ μ μμ΅λλ€.
moduleA
-> moduleB
-> moduleC
-> moduleD
.
moduleB
μμ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ import { ABC } from 'moduleA'
λ₯Ό μνν΄μΌνλ κ²μ
λλ€.
moduleC
moduleB
λ₯Ό μ¬μ©νκ³ μλͺ
μ λ΄λ³΄λΌ λ moduleB
ABC
μμ moduleA
νμ§λ§ μ΄λ²μλ ABC
νμνκΈ° λλ¬Έμ λ€μ μ»΄νμΌμ μ€ν¨ν©λλ€ moduleB
보λ΄μ§ μμμ΅λλ€.
μ΄λ λ€μ μ€ νλλ₯Ό μλ―Έν©λλ€.
moduleC
μꡬμ νλ μμ‘΄ν΄μΌνκΈ° moduleA
κ°μ Έμ¬ ABC
moduleB
λ κ°μ Έ μ€κΈ°λΏλ§ μλλΌ ABC
λ€μ λ΄λ³΄λ΄κ³ moduleC
κ°μ ΈμμΌν©λλ€.moduleD
κ° λΉμ·ν μΌμνλ€λ©΄ κΈ°λ³Έμ μΌλ‘ μ 체 μ’
μμ± μ²΄μΈμ μμμΌν©λλ€.
λλ typings
νκ³ μκ³ λλ₯Ό λ§λ λ¬Έμ κ° μκΈ° λλ¬Έμ μ΄κ²μ΄ μ¬μ€μμ μ¦λͺ
νκΈ° μν΄ μ΄κ²μ ν
μ€νΈ ν μ μμμ΅λλ€ : https://github.com/typings/typings/issues/625 ~~
νΈμ§ : λλ κ·Έκ²μ μ¬ν ν μ μκ³ μ€μ λ‘ λ΄ moduleD
λ κ°μ Έ μ€κΈ°λ₯Ό μν΄ moduleA
λ₯Ό μ°Έμ‘°ν΄μΌν©λλ€.
λ΄ μμμ :
moduleA
=> redux
moduleB
=> redux-thunk
moduleC
=> redux-thunk
μμμλ μ¬μ©μ μ§μ μ½λmoduleD
=> μΌλΆ λμκ΄ABC
=> redux
Dispatch
μΈν°νμ΄μ€@unionalμμ μ€λͺ ν κ²κ³Ό λμΌν λ¬Έμ κ°
μ΄ λ¬Έμ λ₯Ό λ€μμ¬μμμ€. @unional μ μν΄ μ€λͺ λ λ¬Έμ λ λ§€μ° νμ€μ μ΄λ―λ‘ λ€μ λ΄λ³΄λ΄λ μλ λͺ¨λκ³Ό λμΌν μ νμ μ¬μ©νλ©΄μ λΌμ΄λΈλ¬λ¦¬ μμ μ€κ° / λμ°λ―Έ λΌμ΄λΈλ¬λ¦¬λ₯Ό μΆκ°νκΈ°κ° λ§€μ° μ΄λ ΅μ΅λλ€.
https://github.com/Microsoft/TypeScript/issues/9944 νΈλμ λ°ννμ¬ μ μΈ λ°©μΆ λ¨κ³μμ κ°μ Έ μ€κΈ°λ₯Ό μΆκ°ν©λλ€.
κ°μ¬!
κ°μ Έ μ€κΈ°λ₯Ό μΆκ° ν λμ λ¬Έμ μ μ noUnusedLocals
νλ©΄ μ»΄νμΌλ¬κ° μ¬μ©λμ§ μλ μ νμ λν΄ λΆννλ€λ κ²μ
λλ€. λͺ
μ μ μ ν μ£Όμμ μΆκ° ν μ μμ§λ§ μΆλ‘ μ μ»μ§ λͺ»ν©λλ€. μ:
class Whatever {
fetch(uri: string): Promise<void> { }
ensureFetched = MemoizedFunction<(uri: string) => Promise<void>> = memoize((uri: string) => this.fetch(uri))
}
ensureFetched
λν μ ν μ£Όμμ μλ΅νκ³ μΆμ΅λλ€.
μ΄μ λν ν΄κ²° λ°©λ²μ μ°Ύμμ΅λλ€.
tsconfigμμ : include: [ ..., "node_modules/@your_scope/your_library" ]
νμ΄μ λΉλλ€.
@ salim7 μ΄λ κ²νλ©΄ μ»΄νμΌ μκ°μ΄ λλ €μ§κ³ (μ΄λ―Έ μ»΄νμΌ λ λΌμ΄λΈλ¬λ¦¬λ₯Ό λ€μ μ»΄νμΌνκΈ° λλ¬Έμ) λμ λΌμ΄λΈλ¬λ¦¬μ ν¨κ» μ격 μ± μ€μ μ μ΅μ κ³΅ν΅ λΆλͺ¨λ₯Ό μ¬μ©ν΄μΌν©λλ€.
@mhegazy λ¬Έμ λ λ€μ μλ리μ€μμ μ¬νλμμ΅λλ€.
import * as Foo from "./Foo";
export class Bar {
baz = new Foo.Baz(); // Compiler forgot "Foo." prefix in the type, and throws this error, because "Baz" without perfix is not imported.
getBaz() { // All the same
return new Foo.Baz();
}
}
μ루μ μ λͺ μ μ μ νμ μ§μ νλ κ²μ λλ€.
import * as Foo from "./Foo";
export class Bar {
baz: Foo.Baz = new Foo.Baz(); // ok
getBaz(): Foo.Baz { // ok
return new Foo.Baz();
}
}
μμ μνμ μ¬μ©νμ¬ μ¬ν ν μ μμ΅λλ€. μ λ²κ·Έλ₯Ό μ κ³ νκ³ λ¬Έμ λ₯Ό μ¬ν ν μ μλλ‘ λ λ§μ 컨ν μ€νΈλ₯Ό μ 곡νμΈμ.
@PFight κ°μ¬ν©λλ€! κ·Έκ²μ λλ₯Όμν κ²μ΄μλ€!
λ€μμ μ¬μ©ν λ λ°©κΈμ΄ λ¬Έμ μ μ§λ©΄νμ΅λλ€.
export { IMyInterface } from './file'
````
The solution was to do this:
```ts
import { IMyInterface } from './file'
export { IMyInterface }
κ·Έλ¬λ μ΄κ²μ μ λ§λ‘ νμν κ²μ μλλλ€.
noUnusedLocals
λ₯Ό λ€λ£¨λ λ°©λ²μ μμ λΈ μ¬λμ΄ μμ΅λκΉ?
@yordis // @ts-ignore
@ pelotom λ€ μ΄κ²μ μμ ν λ΄ μλͺ»μ λλ€.
λλ ν κ°μ§λ₯Ό μκ°νκ³ λ€λ₯Έ κ²μ μΌμ΅λλ€.
Typescriptκ° noUnusedLocals
μ μ μΈ μ¬μ΄μ λ¬Έμ λ₯Ό ν΄κ²° νμ΅λκΉ?
μ μκ² μμ ν κ³ ν΅μ€λ¬μμ§λ νμ¬μ ν΄κ²° λ°©λ²μ
import {SomeInterface} from "./SomeFile";
const _dummySomeInterface : undefined|SomeInterface = undefined;
_dummySomeInterface;
//Code that implicitly uses SomeInterface
noUnusedLocals
λ₯Ό νΌνκ³ κ°λ₯ν κ²½μ° μ λ€λ¦ μΈν°νμ΄μ€μ λν μ ν μΆλ‘ λ νμ©ν©λλ€.
κ°μ₯ μ μ©ν λκΈ
FWIWλ μΌλ°μ μΌλ‘ Stack Overflowμμ λ λΉ λ₯Έ λ΅λ³μ μ»μ μ μμ§λ§ μ¬κΈ°μλ νλμ μ νν λ μ§λ¬Έμν©λλ€.
μ¬κΈ°μ λ¬Έμ λ
--declaration
νλκ·Έλ₯Ό μ¬μ©νκ³ μμ§λ§ μ»΄νμΌλ¬κ° μμ μ μν ν μμλ λ°©λ²μ μ 곡νμ§ μμλ€λ κ²μ λλ€.ModuleA.d.ts
λ₯Ό λ΄λ³΄λ΄λ €κ³ ν λ μ»΄νμΌλ¬λ λͺ¨λμ λͺ¨μμ λνλ΄λ κ°μ²΄ μ ν 리ν°λ΄ (μ :{ moduleB: { classA: *mumble?* } }
)μ μμ±ν΄μΌν©λλ€. κ·Έλ¬λclassA
μ§μ μ°Έμ‘°νλ μ΄λ¦μ΄ λ²μμ μμΌλ―λ‘ "μ΄λ¦μ μ§μ ν μ μμ"μ νμ΄λ©° μ€λ₯κ° μμ΅λλ€.import
ofClassA
λ₯ΌModuleA.ts
μ μΆκ°νλ©΄ μ€λ₯κ° μ¬λΌμ§λλ€.