[typescript] TypeScript : HTMLElement 캐스팅

누구든지 TypeScript에서 캐스팅하는 방법을 알고 있습니까?

나는 이것을하려고 노력하고있다 :

var script:HTMLScriptElement = document.getElementsByName("script")[0];
alert(script.type);

하지만 오류가 발생했습니다.

Cannot convert 'Node' to 'HTMLScriptElement': Type 'Node' is missing property 'defer' from type 'HTMLScriptElement'
(elementName: string) => NodeList

올바른 유형으로 캐스팅하지 않으면 script 요소의 ‘type’멤버에 액세스 할 수 없지만이를 수행하는 방법을 모르겠습니다. 문서 및 샘플을 검색했지만 아무것도 찾을 수 없습니다.



답변

TypeScript는 ‘<>’를 사용하여 캐스트를 둘러싸므로 위의 내용은 다음과 같습니다.

var script = <HTMLScriptElement>document.getElementsByName("script")[0];

그러나 불행히도 다음을 수행 할 수 없습니다.

var script = (<HTMLScriptElement[]>document.getElementsByName(id))[0];

당신은 오류가 발생

Cannot convert 'NodeList' to 'HTMLScriptElement[]'

그러나 당신은 할 수 있습니다 :

(<HTMLScriptElement[]><any>document.getElementsByName(id))[0];


답변

TypeScript 0.9부터 lib.d.ts파일은 호출에 대한 올바른 유형을 반환하는 특수한 과부하 서명을 사용합니다 getElementsByTagName.

이는 더 이상 유형 어설 션을 사용하여 유형을 변경할 필요가 없음을 의미합니다.

// No type assertions needed
var script: HTMLScriptElement = document.getElementsByTagName('script')[0];
alert(script.type);


답변

캐스트를 입력하지 마십시오. 못. 타입 가드 사용 :

const e = document.getElementsByName("script")[0];
if (!(e instanceof HTMLScriptElement))
  throw new Error(`Expected e to be an HTMLScriptElement, was ${e && e.constructor && e.constructor.name || e}`);
// locally TypeScript now types e as an HTMLScriptElement, same as if you casted it.

컴파일러가 당신을 위해 일을하고 가정이 잘못되면 오류를 얻도록하십시오.

이 경우 과도하게 보일 수 있지만 나중에 다시 와서 DOM에서 누락 된 클래스를 추가하는 것과 같이 선택기를 변경하면 많은 도움이 될 것입니다.


답변

다음을 사용하여 항상 유형 시스템을 해킹 할 수 있습니다.

var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];


답변

결국 :

  • 실제 Array물건 (으로 NodeList차려 입지 않음 Array)
  • 에 포함 HTMLElements되지 Node않고을 포함하도록 보장 된 목록HTMLElement
  • 옳은 일을하는 따뜻한 퍼지 느낌

이 시도:

let nodeList : NodeList = document.getElementsByTagName('script');
let elementList : Array<HTMLElement> = [];

if (nodeList) {
    for (let i = 0; i < nodeList.length; i++) {
        let node : Node = nodeList[i];

        // Make sure it's really an Element
        if (node.nodeType == Node.ELEMENT_NODE) {
            elementList.push(node as HTMLElement);
        }
    }
}

즐겨.


답변

명시적인 리턴 타입으로 변수를 입력 할 수 있습니다 :

const script: HTMLScriptElement = document.getElementsByName(id).item(0);

또는 다음 과 같이 주장하십시오 ( TSX 필요 ).

const script = document.getElementsByName(id).item(0) as HTMLScriptElement;

또는 더 간단한 경우에는 꺾쇠 괄호 구문을 사용하십시오.


형식 어설 션은 다른 언어의 형식 캐스트와 유사하지만 데이터의 특별한 검사 또는 재구성을 수행하지 않습니다. 런타임에 영향을 미치지 않으며 컴파일러가 순수하게 사용합니다.

선적 서류 비치:

TypeScript-기본 유형-유형 어설 션


답변

명확히하기 위해 이것은 정확합니다.

‘NodeList’를 ‘HTMLScriptElement []’로 변환 할 수 없습니다

A는로 NodeList실제 어레이 아니다 (그것이 포함되지 않은 예 .forEach, .slice, .push등).

따라서 HTMLScriptElement[]형식 시스템에서 변환하면 Array.prototype컴파일 타임에 멤버 를 호출하려고하면 형식 오류 가 발생하지 않지만 런타임에는 실패합니다.