2017-12-10 2 views
3

사용할 때 모듈을 가져올 필요없이 모든 곳에서 사용할 수있는 전역 함수를 정의하려고합니다.TypeScript에서 전역 함수를 정의하는 방법은 무엇입니까?

이 함수는 C#에서 사용할 수있는 안전 탐색 연산자 (?)를 대체하기위한 것입니다. 가독성을 위해 함수의 접두어에 모듈 이름을 사용하고 싶지 않습니다.

Global.d.ts :

declare function s<T>(someObject: T | null | undefined, defaultValue?: T | null | undefined) : T; 

Global.tsx :

///<reference path="Global.d.ts" /> 

export function s<T>(object: T | null | undefined, defaultValue: T | null = null = {} as T) : T { 
    if (typeof object === 'undefined' || object === null) 
     return defaultValue as T; 
    else 
     return object; 
} 

App.tsx (루트 타이프 라이터 파일) :

import 'Global'; 

다른 TSX 파일 (방법 사용) :

s(s(nullableVar).member).member; //Runtime error 

그러나이 컴파일러는 괜찮 으면 브라우저에서 's is not a function'을 던집니다.

답변

3

컴파일러의 유형을 정의했지만 브라우저의 window (노드의 경우 global)은 전역 이름 공간에 실제로 연결하지 않습니다. 모듈에서 내보내기하는 대신 첨부하십시오. 동형 사용을 위해,

function s() { ... } 

// must cast as any to set property on window 
const _global = (window /* browser */ || global /* node */) as any 
_global.s = s 

당신은 또한 .d.ts 파일을 도랑 declare global를 사용하여 동일한 파일 형식을 선언 할 수 있습니다, 예를 들면 ... 같은 것을 사용 export 키워드를 제거하고 전역 개체를 증가시키기 위해 몇 가지 코드를 추가 : 조금 비틀기

// we must force tsc to interpret this file as a module, resolves 
// "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations." 
// error 
export {} 

declare global { 
    function s<T>(someObject: T | null | undefined, defaultValue?: T | null | undefined) : T; 
} 

const _global = (window /* browser */ || global /* node */) as any 
_global.s = function<T>(object: T | null | undefined, defaultValue: T | null = null) : T { 
    if (typeof object === 'undefined' || object === null) 
    return defaultValue as T; 
    else 
    return object; 
} 
+0

, 나는'재산권의이 'Window'''유형에 존재하지 않는 수. 두 번째 해결 방안으로,'전역 범위에 대한 증강은 외부 모듈 또는 주변 모듈 선언에 직접 중첩 될 수 있습니다 .'라고합니다. – sixtstorm1

+0

또한 dts 파일의 내 함수를'declare global {...}'안에 감싸려고했지만, 함수를 사용할 때 컴파일시'name을 찾을 수 없습니다 '라는 오류가 발생합니다. .s', 나는 싫어. – sixtstorm1

+0

내 대답을 편집했습니다. 잘하면 도움이됩니다. – CaseyWebb

1

global.ts(x) 요구는 유효 "전역 모듈"(만 부작용 모듈) 수 있습니다. 동일한 파일에 전역 선언을 제공하고 global.d.ts을 제거 할 수도 있습니다. 그것을 사용하려면

function _s<T>(object: T | null, defaultValue: T = {} as T) : T { 
    return object == null 
     ? defaultValue 
     : object as T; 
} 

// Global declaration 
declare var s: typeof _s; 

// Global scope augmentation 
var window = window || null; 
const _global = (window || global) as any; 
_global.s = _s; 

, 그냥 글로벌 가져 오기를 통해 App.tsx에서 예를 들어, 한 번 모듈을 가져옵니다 import './global';.

는 모카, 차이, TS-노드 테스트 : 첫 번째 솔루션

import { expect } from 'chai'; 
import './global'; // To do once at app bootstrapping 

describe('global s()',() => { 
    it('should replace null with empty object',() => { 
     const result = s(null); 
     expect(result).to.eql({}); 
    }); 

    it('should replace undefined with empty object',() => { 
     const result = s(undefined); 
     expect(result).to.eql({}); 
    }); 

    it('should replace null with the given default value',() => { 
     const defVal = { def: 'val' }; 
     const result = s(null, defVal); 
     expect(result).to.eql({ def: 'val' }); 
    }); 

    it('should preserve defined object',() => { 
     const object = { bar: 'a' }; 
     const result = s(object); 
     expect(result).to.eql(object); 
    }); 
}); 
+0

그래, 이건 내가 CaseeyWebb의 대답을 기반으로 한거야. 고마워요 – sixtstorm1

+0

@ sixtstorm1 : 멋지다! 그것이 완전히 작동하는 대답이기 때문에 다음 독자가 유용하지만 유익한 대답이 아닌 우선 순위로 리디렉션되도록하기 위해 (또는 적어도 "+"를 추가하여) 표시해 주실 수 있습니까? –

+0

예 답변을 upvoted했습니다. – sixtstorm1

관련 문제