문제

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

올바른 유형으로 캐스팅하지 않으면 스크립트 요소의 '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);

항상 유형 시스템을 해킹 할 수 있습니다 :

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

캐스트를 입력하지 마십시오.못.유형 경비원 사용 :

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.
.

컴파일러가 당신을 위해 일하고 가정이 잘못 될 때 오류를 얻게하십시오.

이 경우에 과도하게 보일 수 있지만 나중에 다시 돌아오고, 예를 들어 누락 된 클래스를 추가하는 것과 같은 선택자를 변경하면 많은 도움이됩니다.

To end up with:

  • an actual Array object (not a NodeList dressed up as an Array)
  • a list that is guaranteed to only include HTMLElements, not Nodes force-casted to HTMLElements
  • a warm fuzzy feeling to do The Right Thing

Try this:

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);
        }
    }
}

Enjoy.

Just to clarify, this is correct.

Cannot convert 'NodeList' to 'HTMLScriptElement[]'

as a NodeList is not an actual array (e.g. it doesn't contain .forEach, .slice, .push, etc...).

Thus if it did convert to HTMLScriptElement[] in the type system, you'd get no type errors if you tried to call Array.prototype members on it at compile time, but it would fail at run time.

Updated example:

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

Documentation:

TypeScript - Basic Types - Type assertions

This seems to solve the problem, using the [index: TYPE] array access type, cheers.

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

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

Could be solved in the declaration file (lib.d.ts) if TypeScript would define HTMLCollection instead of NodeList as a return type.

DOM4 also specifies this as the correct return type, but older DOM specifications are less clear.

See also http://typescript.codeplex.com/workitem/252

Since it's a NodeList, not an Array, you shouldn't really be using brackets or casting to Array. The property way to get the first node is:

document.getElementsByName(id).item(0)

You can just cast that:

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

Or, extend NodeList:

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

I would also recommend the sitepen guides

https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript/ (see below) and https://www.sitepen.com/blog/2014/08/22/advanced-typescript-concepts-classes-types/

TypeScript also allows you to specify different return types when an exact string is provided as an argument to a function. For example, TypeScript’s ambient declaration for the DOM’s createElement method looks like this:

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

This means, in TypeScript, when you call e.g. document.createElement('video'), TypeScript knows the return value is an HTMLVideoElement and will be able to ensure you are interacting correctly with the DOM Video API without any need to type assert.

var script = (<HTMLScriptElement[]><any>document.getElementsByName(id))[0];    
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top