2011-10-25 4 views
2

Google Closure Compiler로 놀고있는 동안 잘못된 변수 유형에 대한 경고를 컴파일러에서 강제로 실행할 수없는 경우를 발견했습니다. 다음 샘플을 사용했습니다 :배열에 대한 Google Closure 컴파일러 유형 annotations

/** @typedef ({name: string, token: string}) */ 
var pendingItem; 

/** @type (Array.<pendingItem>) */ 
var pending = []; 

// NOTICE: the token is intentionally misspelled as "toke" to cause a warning 
var dummyItem = { 
    name: 'NameHere', 
    toke: 'SomeToken' 
}; 

// This should cause a warning, because of the 
// type mismatch (toke instead of token) 
pending.push(dummyItem); 

// Do something useful so that the whole code wouldn't be optimized to 0 bytes 
alert(pending.length); 

그리고 예상되는 유형 경고 대신 완벽하게 컴파일됩니다. 그러나 사용하는 경우 :

pending[1] = { 
    name: 'Second Name', 
    toke: 'Second Token' 
} 

예상되는 형식 불일치 경고가 나타납니다.

push은 내장 기능이기 때문에 유형 검사가 정의되어 있지 않기 때문일 수도 있습니다. 배열 pendingpendingItem의 배열로 정의하면 강제로 실행되지만 기본값은 아닙니다.

질문은 위의 예에서 경고를 줄 수 있도록 push과 같이 이미 정의 된 함수에 유형 검사를 추가 할 수 있는지 여부와 문제입니다. 또한 비슷한 결과를 얻는 한 가지 방법은 유형을 강제로 앞에 /** @type {pendingItem} */을 추가하는 것이지만 교육 목적으로는 push (또는 더 엄격한 정의 pending)과 같은 함수에 유형 검사를 추가하는 방법에 대해 알고 싶습니다. .

또한 누군가가 객체 속성의 이름을 바꾸는 논리를 설명 할 수 있습니까? 위의 예를 컴파일하면 dummyItem의 속성이 name으로 바뀌지 않지만 tokena으로 바뀝니다.

답변

2

push에서 유형 검사를 강제하려면 올바른 유형의 코드로 다시 정의해야합니다. 객체 리터럴 표기법을 사용하면 @param 대신 @type을 사용하여 유형을 정의해야합니다. 일반 함수를 정의하지 않고 객체의 매개 변수에 함수를 할당하기 때문입니다.

/** @type {function(pendingItem)} */ 
pending.push = function(item) { 
    Array.prototype.push.call(pending, item); 
}; 

지금 다음 컴파일 할 때 : 예상처럼

// Still an intentionally misspelled "toke" 
var dummyItem = { 
    name: 'NameHere', 
    toke: 'SomeToken' 
}; 

// First warning 
pending.push(dummyItem); 

// Second warning 
pending[1] = { 
    name: 'Second name', 
    toke: 'Second Token' 
}; 

그런 다음 모두는 형식 불일치 경고를 생성합니다이 경우 다음과 같은 것입니다.

앞으로 누군가에게 유용 할 수 있다고 생각합니다.

관련 문제