2017-11-30 3 views
2

의 클래스에 설정하는 것이 유효 동적 오브젝트 나는 타이프 라이터와 약간의 재생이 발견된다왜 타이프

class Greeter { 
    e: number; 

    p: boolean = true; 
} 

const xxx = new Greeter(); // true 
console.log(xxx instanceof Greeter); 
const xxx2: Greeter = { e: 1, p: true }; // <--- 1. why is this valid? 
console.log(xxx2 instanceof Greeter); // false 

const xxx3: Greeter = Object.setPrototypeOf({ e2: 1 }, Greeter.prototype); // <-- 2. no warning? 
console.log(xxx2 instanceof Greeter); // true 

그래서 제 질문은 다음과 같습니다

  1. 왜 그것을이다 typescript에서 유효하다. 실제 객체가 아닌 클래스 객체에 동적 객체를 할당한다. 진짜 수업이 아닌 것 같습니다. 향후 개선 될 예정입니까?

  2. 해킹 인 것 같습니다. 그러나 형식에 대해 깨끗한 Typescript 함수는 없습니다. 이것은 더 깨끗한 것이어야하며, 더 나은 검사 기능이 있습니까?

엄격한 옵션이있는 Typescript 2.4.2를 사용합니다.

+0

이기 때문에 typescript는 [duck typing] (https://www.typescriptlang.org/docs/handbook/interfaces.html)을 사용하기 때문에 –

+0

typescript는 실제로 컴파일 유형을 검사하는 것으로 실제 유형의 마술은 수행하지 않습니다. 자바 스크립트 코드. –

+0

덧붙여 말하자면, 첫 번째 오류는 [flow] (https://flow.org)에 의해보고되므로 흐름이 사용자 요구에 더 잘 맞을 수 있습니다. TypeScript는 구조체 타이핑을 사용하고, 객체가 생성 된 방식을 사용합니다 (특히, 클래스 생성자로 수행했는지 여부 - 이것은'instanceof' 검사에 관한 것입니다). TypeScript 유형 시스템의 일부가 아니며 변경되지 않습니다. – artem

답변

2

에 대해 아무것도 모르는 자바 스크립트

const xxx2: Greeter = { e: 1, p: true }; 

converts to --> 

var xxx2 = { e: 1, p: true }; 

을받을 경우 typescript에서 실제 객체 클래스가 아닌 클래스 객체에 동적 객체를 할당하는 것이 왜 유효합니까? 진짜 수업이 아닌 것 같습니다.

타이프 라이터는 구조적인 언어가 아닌 명목상의 언어입니다. 이는 구조가 검사되고 호환 가능한 유형을 사용할 수 있음을 의미합니다. 이 언어 기능에 익숙해지기 시작하면 명목 타이핑으로 너트가 몰리게됩니다.

이 앞으로 개선 할 것인가?

그것은 개선 될 수 없습니다! 구조적 유형 락 :).

하지만 적절한 대답은 "아니오 - 설계 상으로는"입니다.

const xxx3: Greeter = Object.setPrototypeOf({ e2: 1 }, Greeter.prototype); 해킹 인 것 같습니다. 그러나 형식에 대해 깨끗한 Typescript 함수는 없습니다. 이것은 더 깨끗한 것이어야하며, 더 나은 검사 기능이 있습니까?

이 사람은 약간의 해체를 필요로한다. any :

첫 부분 타이프의 동적 유형이 존재한다는 것이다. 유형이 any 인 것은 변신과 같습니다. 글자 그대로 일 수 있습니다. 유형입니다. 컴파일러는 길에서 유지하고 동적 유형을 사용할 수 있도록 할 때마다

당신은 any를 사용할 수 있습니다. (동적 "형식이 동적으로 변경 될 수 있음"에서 동적 리터럴을 다이나믹으로 묘사했음을 알지만 공식 동적 유형에 대해서는 여기에서 설명합니다).

Object.setPrototypeOf(...)을 호출하면 any 유형의 이러한 특수 동적 유형 중 하나가 반환됩니다.

즉, 형식이 Greeter 인 변수에 할당하면 any 유형이 있기 때문에 허용됩니다.

귀하의 시도가 실망 스러울 수도 있지만, 달성하고자하는 것이 가능하다고 확신합니다. 무엇을해야 할지를 자유롭게 물어보십시오. 도와 줄 수있는 방법을 찾으십시오.

+0

@JLRishe 나는 확실히 그랬다. 그게 흥분이 통신 할 수있는 능력입니다 :) 편집 됨. – Fenton

0

여기에서 귀하의 related Github issue이 있습니다.

@ Fenton의 정확한 answer은 TypeScript에서 지원되는 구조 형에 대한 칭찬입니다. 하나는 자신이 nominal typing의 금단의 열매의 생각을 접대 판단되는 경우를 위해, 그러나, 실제로 해결 방법이 있습니다 : 나는 그래서 당신은 더 이상 리터럴 객체를 할당 할 수 없습니다 Greeterprivate member를주는 것이 좋습니다

. 개인 클래스 멤버는 공칭 타이핑에 대한 "표준"TypeScript 해결 방법 인 것 같습니다.

예 :

class Greeter { 
    private _nominal = true; // add something like this 
    e: number; 
    p: boolean = true; 
} 

const xxx = new Greeter(); 
const xxx2: Greeter = { e: 1, p: true }; // error, missing _nominal 
const xxx3: Greeter = { e: 1, p: true, _nominal: true }; // error, _nominal is private 

당신을 위해 그 일을합니까? 즉 적어도 당신이 정말로하려고하면, 당신은 성공하지만 더 어렵게, 스스로 발을 쏠 수 있도록합니다 도움이

// don't do this 
const xxx4: Greeter = function() { return "ha ha fooled you";} as any as Greeter; 

희망; 행운을 빕니다!