TypeScript : 유형 시스템 문제
VisualStudio 2012에서 typescript를 테스트하고 있으며 유형 시스템에 문제가 있습니다. 내 HTML 사이트에는 ID가 "mycanvas"인 캔버스 태그가 있습니다. 이 캔버스에 직사각형을 그리려고합니다. 다음은 코드입니다.
var canvas = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
불행히도 VisualStudio는 다음과 같이 불평합니다.
'HTMLElement'유형의 값에 'getContext'속성이 없습니다.
두 번째 줄을 오류로 표시합니다. 나는 이것이 단지 경고라고 생각했지만 코드가 컴파일되지 않습니다. VisualStudio는 다음과 같이 말합니다.
빌드 오류가 있습니다. 계속해서 마지막으로 성공한 빌드를 실행 하시겠습니까?
이 오류가 전혀 마음에 들지 않았습니다. 동적 메서드 호출이없는 이유는 무엇입니까? 모든 메소드 getContext가 내 캔버스 요소에 확실히 존재합니다. 하지만이 문제는 해결하기 쉬울 것이라고 생각했습니다. 캔버스에 대한 유형 설명을 추가했습니다.
var canvas : HTMLCanvasElement = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
그러나 유형 체계는 여전히 만족스럽지 않았습니다. 이번에는 첫 번째 줄에 새로운 오류 메시지가 있습니다.
'HTMLElement'를 'HTMLCanvasElement'로 변환 할 수 없음 : 'HTMLElement'유형에 'HTMLCanvasElement'유형의 'toDataURL'속성이 없습니다.
글쎄, 나는 정적 인 타이핑을 좋아하지만 이것은 언어를 사용할 수 없게 만듭니다. 유형 시스템은 내가 무엇을하기를 원합니까?
최신 정보:
Typescript는 실제로 동적 호출을 지원하지 않으며 내 문제는 typecast로 해결할 수 있습니다. 내 질문은 기본적 으로이 TypeScript 의 복제본입니다 .HTMLElement 캐스팅
var canvas = <HTMLCanvasElement> document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
또는 any
유형 과 함께 동적 조회 사용 (유형 검사 없음) :
var canvas : any = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
lib.d.ts 에서 다양한 유형을 볼 수 있습니다 .
const canvas = document.getElementById('stage') as HTMLCanvasElement;
TypeScript의 .9 버전에서 수정되고있는 것 같습니다. http://blogs.msdn.com/b/typescript/archive/2013/03/25/working-on-typescript-0-9-generics-overload- on-constants-and-compiler-performance.aspx 캔버스 태그가 명시 적으로 표시되는 "상수 오버로드"섹션을 참조하십시오.
나는 같은 문제가 있었지만 HTMLCanvasElement 대신 SVGSVGElement를 사용했습니다. SVGSVGElement로 캐스팅하면 컴파일 타임 오류가 발생했습니다.
var mySvg = <SVGSVGElement>document.getElementById('mySvg');
'HTMLElement'를 'SVGSVGElement'로 변환 할 수 없습니다.
'HTMLElement'유형에 'SVGSVGElement'유형의 'width'속성이 없습니다.
'SVGSVGElement'유형에 'HTMLElement'유형의 'onmouseleave'속성이 없습니다.
먼저 'any'로 캐스팅하여 수정 한 경우 :
var mySvg = <SVGSVGElement><any>document.getElementById('mySvg');
또는 이런 식으로 (동일한 효과가 있음)
var mySvg: SVGSVGElement = <any>document.getElementById('mySvg');
이제 mySvg는 SVGSVGElement로 강력하게 입력됩니다.
다른 답변은 유형 어설 션을 장려하지만 (그게 바로 TypeScript에는 유형 을 실제로 변경하는 유형 캐스트 가 없습니다 . 유형 검사 오류를 억제하는 방법 일뿐입니다) 문제에 접근하는 지적으로 정직한 방법은 오류 메시지.
귀하의 경우 잘못 될 수있는 세 가지가 있습니다.
document.getElementById("mycanvas")
might returnnull
, because no node of that id is found (it might have been renamed, not injected to the document yet, someone might have tried running your function in an environment without access to DOM)document.getElementById("mycanvas")
might return a reference to a DOM element, but this DOM element is not aHTMLCanvasElement
document.getElementById("mycanvas")
did return a validHTMLElement
, it is indeed anHTMLCanvasElement
, but theCanvasRenderingContext2D
is not supported by the browser.
Instead of telling the compiler to shut up (and possibly finding yourself in a situation where a useless error message like Cannot read property 'getContext' of null
is thrown), I recommend taking control over your application boundaries.
Make sure the element contains a HTMLCanvasElement
const getCanvasElementById = (id: string): HTMLCanvasElement => {
const canvas = document.getElementById(id);
if (!(canvas instanceof HTMLCanvasElement)) {
throw new Error(`The element of id "${id}" is not a HTMLCanvasElement. Make sure a <canvas id="${id}""> element is present in the document.`);
}
return canvas;
}
Make sure the rendering context is supported by the browser
const getCanvasRenderingContext2D = (canvas: HTMLCanvasElement): CanvasRenderingContext2D => {
const context = canvas.getContext('2d');
if (context === null) {
throw new Error('This browser does not support 2-dimensional canvas rendering contexts.');
}
return context;
}
Usage:
const ctx: CanvasRenderingContext2D = getCanvasRenderingContext2D(getCanvasElementById('mycanvas'))
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
참고URL : https://stackoverflow.com/questions/13669404/typescript-problems-with-type-system
'Programing' 카테고리의 다른 글
httpclient 호출에서 콘텐츠 본문을 가져 오는 방법은 무엇입니까? (0) | 2020.09.20 |
---|---|
jQuery Validate Plugin-단일 필드의 유효성 검사 트리거 (0) | 2020.09.20 |
VSCode : Mac OSX에서 Enter 키를 사용하여 파일 탐색기에서 파일 열기 (0) | 2020.09.20 |
UNIX에서 널 문자 식별 및 제거 (0) | 2020.09.20 |
어셈블리 언어를 배우는 것이 가치가 있습니까? (0) | 2020.09.20 |