다른 속성 값을 기반으로 클래스 속성 유형을 암시할 수 있습니까?

마운틴 트레일

한 속성의 유형이 다른 값에 의해 암시될 수 있는 방식으로 클래스 또는 해당 속성을 입력할 수 있습니까?

유형 testWithTyping을 사용하는 방법에서 알 수 있듯이 MyType.

최종 목표는 속성 x속성 이면 가치 가 있음 true클래스에 알릴 수 y있는 것입니다.

예제 코드:

type MyType = { isSet: false, id: null } | { isSet: true, id: number };

class MyClass {
  isSet: boolean = false;
  id: number | null = null;

  constructor(id?: number) {
    if (typeof id === 'number' && id > 0) {
      this.isSet = true;
      this.id = id;
    }
  }

  test() {
    if (this.isSet) {
      this.logId(this.id); // TS2345:
      // Argument of type 'number | null' is not
      // assignable to parameter of type 'number'.
    }
  }

  testWithTyping(this: this & MyType) {
    if (this.isSet) {
      this.logId(this.id); // Works!
    }
  }

  logId(id: number) {
    console.log(id);
  }
}
jcalz

TypeScript에서 클래스와 인터페이스는 현재 공용체 유형을 구현하도록 선언할 수 없습니다. 그것은되었습니다 제안 ,하지만 아무것도 아직 발생하지 않았다. 따라서 컴파일러가 그것이 MyClass extends MyType사실임 을 이해하는 쉬운 방법은 없습니다 .

이 문제를 처리하기 위해 내가 생각할 수 있는 두 가지 방법은 코드를 리팩토링하는 것과 관련이 있습니다. 의 인스턴스가있는 경우 MyClass입니다 가능성이 앞뒤로 두 유형 간의 전환 MyType(첫번째 그것의, 예를 들어 {isSet: false, id: null}, 다음 나중에이다 {isSet: true, id: 123}, 그럼 내가 만드는 권하고 싶습니다) MyClass MyType 대신 MyType. 이것은 상속에 대한 일종의 합성 입니다. 내가 하는 방법은 다음과 같습니다.

class MyClass {
    myType: MyType = { isSet: false, id: null };

    constructor(id?: number) {
        if (typeof id === 'number' && id > 0) {
            this.myType = { isSet: true, id };
        }
    }

    test() {
        if (this.myType.isSet) {
            this.logId(this.myType.id);
        }
    }
    logId(id: number) {
        console.log(id);
    }
}

주에 대한 모든 참조 것을 this.isSet또는 this.id교환되었다 this.myType.isSetthis.myType.id.

그리고 당신은 그것을 테스트할 수 있습니다:

const s = new MyClass(123);
s.test(); // 123
const u = new MyClass();
u.test(); // nothing

다른 방법은 그 그것을 만족에게 당신의 독창적 인 생각을 할 거라고 MyClass인스턴스가 실제로 있는 MyType 의, 그러나 개인 경우에만 작동 MyClass인스턴스는 항상 하나 또는의 다른 구성원이 될 것입니다 MyType노동 조합 및 변경하지 마십시오. 이 경우 다음 MyClass과 같이 두 개의 관련된 클래스의 합집합을 얻을 수 있습니다.

abstract class MyClassBase {
    abstract isSet: boolean;
    abstract id: number | null;
    abstract test(): void;
    logId(id: number) {
        console.log(id);
    }
}

class MyClassSet extends MyClassBase implements Extract<MyType, { isSet: true }>{
    readonly isSet = true;
    readonly id: number;
    constructor(id: number) {
        super();
        this.id = id;
    }
    test() {
        this.logId(this.id);
    }
}

class MyClassUnset extends MyClassBase implements Extract<MyType, { isSet: false }> {
    readonly isSet = false;
    readonly id = null;
    constructor() {
        super();
    }
    test() { }
}

type MyClass = MyClassSet | MyClassUnset;
const MyClass = class {
    constructor(id?: number) {
        return (typeof id === 'number' && id > 0) ?
            new MyClassSet(id) : new MyClassUnset();
    }
} as new (id?: number) => MyClass;

따라서 MyClassSet둘 다 , 모든 공통 기능을 넣을 추상 클래스의 MyClassUnset하위 클래스입니다 MyClassBase. this: MyType거기에 메소드 매개변수 를 지정해야 한다면 그렇게 하는 것이 좋습니다. 그러나 설정 여부에 따라 다른 기능은 해당 하위 클래스에서 구현해야 하므로 그렇게 해서는 안 됩니다.

그런 다음 MyClass유형은 MyClassSet의 합집합이며 를 반환하는 생성자를 MyClassUnset만들 수도 있습니다 .MyClassMyClass

테스트는 이전과 동일하게 작동합니다.

const s = new MyClass(123);
s.test(); // 123
const u = new MyClass();
u.test(); // nothing

나는 일반적으로 구현을 시도하는 대신 MyClass유형의 속성을 보유하는 첫 번째 솔루션을 선호합니다 . 왜냐하면 그것이 더 간단하기 때문입니다. 그러나 때로는 클래스 계층도 유용합니다.MyTypeMyType

알겠습니다. 도움이 되기를 바랍니다. 행운을 빕니다!

코드 링크

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

다른 속성 값으로 변수의 속성 유형을 추론 할 수 있습니까?

클래스 속성 유형을 참조 할 수 있습니까?

객체의 다른 속성을 기반으로 유형을 추론 할 수 있습니까?

사전을 다른 클래스 인스턴스의 속성으로 할당 할 수 있습니까?

C #에서 다른 유형을 사용하여 클래스의 공용 속성을 초기화 할 수 있습니까?

클래스를 토글 할 때 다른 값으로 동일한 CSS 속성을 사용할 수 없습니다.

CSS 만 사용하면 클래스 이름을 기반으로 속성을 설정할 수 있습니까?

다중 매개 변수 유형 클래스 및 기능 종속성이 할 수없는 유형 패밀리는 무엇을 할 수 있습니까?

다른 클래스로 전달하는 클래스의 속성 값을 어떻게 설정할 수 있습니까?

Typescript는 값이 다른 유형의 속성 이름으로 사용될 클래스 속성을 만듭니다.

클래스 속성의 유형을 어떻게 선언 할 수 있습니까?

다른 열의 공통 속성 값을 기반으로 한 열의 속성 값을 나열 할 수 있습니까?

Bolt CMS : 다른 필드 값을 기반으로 콘텐츠 유형 제목을 생성 할 수 있습니까?

TypeScript : 추상에 지정된 유형에서 상속 된 속성으로 추상 클래스 속성을 구현할 수 있습니까?

Python, 클래스에는 속성이 없습니다. 클래스에 전달 된 값의 값을 어떻게 반환 할 수 있습니까?

내 클래스가 Swift에서 프로토콜 속성 유형을 재정의 할 수 있습니까?

상위 구성 요소를 기반으로 구성 요소 속성 유형을 추론 할 수 있습니까?

다른 속성을 기반으로 속성 값을 자동으로 설정하고 나중에 사용할 수 있도록 캐시합니다.

기본 값을 조정할 수있는 속성 클래스를 만드시겠습니까?

동일한 유형 / 클래스의 객체가 다른 데이터 속성을 가질 수 있습니까?

할당 연산자를 오버로드하여 클래스 속성 값을 반환할 수 있습니까?

두 가지 다른 속성을 기반으로 최신 행을 어떻게 선택할 수 있습니까?

부분 클래스의 속성에 속성을 추가 할 수 있습니까?

WMI에서 클래스 속성을 쿼리하고 다른 클래스 속성을 사용하여 필터링할 수 있습니까?

Angular 2 Typescript 클래스 속성을 사용하면 잘못된 유형을 할당 할 수 있습니다.

클래스 속성을 장식 할 수 있습니까?

PHP에서 클래스 속성 값을 동적으로 정의 할 수 있습니까?

적합한 기본 클래스를 찾을 수 없습니다. 'mainClass'속성을 추가하십시오.-잘못된 클래스 경로 일 수 있습니까?

목록을 클래스 속성으로 전달할 수 없습니다.

TOP 리스트

  1. 1

    C # 16 진수 값 0x12는 잘못된 문자입니다.

  2. 2

    Matlab의 반복 Sortino 비율

  3. 3

    Python의 csv 파일에서 첫 번째 열 삭제

  4. 4

    개체 참조가 개체의 인스턴스로 설정되지 않았습니까? (예외 오류 ~ ASP.NET MVC)

  5. 5

    atob은 인코딩 된 base64 문자열을 디코딩하지 않습니다.

  6. 6

    EventEmitter <string>의 컨텍스트 'this'가 Observable <string> 유형의 'this'메서드에 할당되지 않았습니다.

  7. 7

    병합 셀을 사용하여 워크 시트의 데이터 필터링

  8. 8

    PhpStorm 중단 점에서 변수 값을 볼 수 없습니다.

  9. 9

    jQuery에서 이벤트 핸들러를 제거하는 가장 좋은 방법은 무엇입니까?

  10. 10

    `@ Transactional`이 있음에도 불구하고 이러한 데이터베이스 수정 사항이 롤백되지 않는 이유는 무엇입니까?

  11. 11

    ssh를 사용하여 원격에서 로컬로 파일 복사

  12. 12

    종속 사용자 정의 Lightning 선택 목록 Level2 및 Level3을 설정한 다음 Lightning 구성 요소에서 Level2를 재설정하지만 Level2 캐시 데이터가 저장됨

  13. 13

    2 개의 이미지를 단일 평면 이미지로 결합

  14. 14

    팝업처럼 위젯을 표시하는 방법

  15. 15

    [해결] 쿠키 설정 SameSite = Chrome / JSP, JAVASCRIPT에서 작동하지 않습니다.

  16. 16

    버튼 클릭을 기반으로 특정 CSS 클래스를 추가하는 방법은 무엇입니까?

  17. 17

    React 구성 요소가 자동으로 초기 상태로 다시 렌더링됩니다.

  18. 18

    연결된 서버 쿼리는 작동하지만 동일한 OPENQUERY는 "sys.servers에서 서버 'SERVER'를 찾을 수 없습니다.

  19. 19

    파일 2의 파일 1에서 동일한 줄을 조건으로 바꿉니다.

  20. 20

    아이디어 Intellij : 종속성 org.json : json : 20180813을 찾을 수 없음, maven에서 org.json 라이브러리를 가져올 수 없음

  21. 21

    상황에 맞는 메뉴 색상

뜨겁다태그

보관