TypeScript : HTMLElement 캐스팅


198

누구든지 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'멤버에 액세스 할 수 없지만이를 수행하는 방법을 모르겠습니다. 문서 및 샘플을 검색했지만 아무것도 찾을 수 없습니다.


이 캐스팅 문제는 더 이상 0.9에 존재하지 않습니다. 아래 @Steve의 답변을 참조하십시오.
Greg Gum

@GregGum 나는 스티브가 대답을 보이지 않아요
스티브 Schrab을

답변:


255

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];

나는 그들이 이것을 더 조사해야한다고 생각한다. $ ( '[type : input]'). each (function (index, element)를 사용하고 설정해야 할 속성에 따라 HTMLInputElement 또는 HTMLSelectElement로 캐스트 할 요소가 필요하다고 가정하십시오. / get, 캐스팅 사용 (<HTMLSelectElement> <any> element) .selectedIndex = 0; 추악한 요소 주위에 ()를 추가합니다
rekna

내 질문에 답변 한 +1 stackoverflow.com/questions/13669404/…
lhk

장기적으로 (0.9가 나간 후) NodeList <HtmlScriptElement>와 같은 것으로 캐스팅 할 수 있어야하며 getElementsByName은 문자열 리터럴 유형 재정의를 사용하여 전혀 캐스팅하지 않고이를 올바르게 얻을 수 있습니다!
Peter Burns

3
1.0 이후 구문은 다음과 같아야합니다.(<NodeListOf<HTMLScriptElement>>document.getElementsByName(id))[0];
Will Huang

1
as를 사용하여 캐스트 할 수도 있습니다. var script = document.getElementsByName ( "script") [0] as HTMLScriptElement;
JGFMK

36

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

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

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

객체 표기법으로 어떻게합니까? 즉, {name : <HTMLInputElement> : document.querySelector ( '# app-form [name]'). value,}을
Nikos

3
작동 : name : (<HTMLInputElement> document.querySelector ( '# app-form [name]')). value,
Nikos

22

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

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에서 누락 된 클래스를 추가하는 것과 같이 선택기를 변경하면 많은 도움이 될 것입니다.


21

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

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

<any>를 사용하면 이스케이프 유형 검사가 가능하지만 개발 중에 이상적이지는 않지만 멋지다
tit

13

결국 :

  • 실제 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);
        }
    }
}

즐겨.


10

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

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

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

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

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


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

선적 서류 비치:

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


9

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

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

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

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


1
그것은 정확하지만 완전히 유용하지는 않습니다. 대안은 무엇이든 유용한 타입 검사를 제공하지 않는 'any'를 이용하는 것입니다.
Spongman

3

이것은 [index: TYPE]배열 액세스 유형을 사용하여 문제를 해결하는 것처럼 보입니다 .

interface ScriptNodeList extends NodeList {
    [index: number]: HTMLScriptElement;
}

var script = ( <ScriptNodeList>document.getElementsByName('foo') )[0];

1

TypeScript가 NodeList 대신 HTMLCollection을 반환 유형으로 정의하면 선언 파일 (lib.d.ts)에서 해결할 수 있습니다.

DOM4는 이것을 올바른 반환 유형으로 지정하지만 오래된 DOM 사양은 명확하지 않습니다.

http://typescript.codeplex.com/workitem/252 참조


0

NodeList아닌 이므로 Array괄호를 사용하거나에 캐스팅해서는 안됩니다 Array. 첫 번째 노드를 얻는 속성 방법은 다음과 같습니다.

document.getElementsByName(id).item(0)

당신은 그것을 캐스팅 할 수 있습니다 :

var script = <HTMLScriptElement> document.getElementsByName(id).item(0)

또는 다음을 확장하십시오 NodeList.

interface HTMLScriptElementNodeList extends NodeList
{
    item(index: number): HTMLScriptElement;
}
var scripts = <HTMLScriptElementNodeList> document.getElementsByName('script'),
    script = scripts.item(0);

1
업데이트 캐스팅은 이제 다음과 같습니다 : const script = document.getElementsByName(id).item(0) as HTMLScriptElement;
Mike Keesey

즉, TS 2.3의 경우 "이렇게 보입니다".
markeissler

0

또한 사이트 펜 가이드를 추천합니다

https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript/ (아래 참조) 및 https://www.sitepen.com/blog/2014/08/22/advanced -타입 스크립트-개념-클래스-타입 /

TypeScript를 사용하면 정확한 문자열이 함수의 인수로 제공 될 때 다른 반환 유형을 지정할 수 있습니다. 예를 들어 DOM의 createElement 메소드에 대한 TypeScript의 앰비언트 선언은 다음과 같습니다.

createElement(tagName: 'a'): HTMLAnchorElement;
createElement(tagName: 'abbr'): HTMLElement;
createElement(tagName: 'address'): HTMLElement;
createElement(tagName: 'area'): HTMLAreaElement;
// ... etc.
createElement(tagName: string): HTMLElement;

즉, typeScript에서 document.createElement ( 'video')를 호출하면 TypeScript는 반환 값이 HTMLVideoElement라는 것을 알고 assert를 입력 할 필요없이 DOM 비디오 API와 올바르게 상호 작용할 수 있습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.