왜 타이프 라이터를 허용하지 않 순환을 참조에 제네릭?

0

질문

여기에 예를 입력 직접 참조 자체를 정의에 해당하지만,경우 추상화를 통해 일반 그것은 완전히 실패한다.

type a = { val: a }; // <-- doesn't care about circular references!

type record<T> = { val: T };

type b = record<b>; // <-- doesn't work!

type func<T> = (arg: T) => void;

type c = func<c>; // <-- doesn't work!

type d = (arg: d) => void; // <-- works!?
types typescript
2021-11-23 20:48:45
2

최고의 응답

3

microsoft/호환되지 않습니#41164 을 위한 표준 이 질문에 대답.

타이프 라이터 허용 순환을 참조에서 일반 인터페이스일반적인 클래스,이후 인터페이스 클래스의 인스턴스가 정적으로 알려진 숙박 시설/회원/법 키를들고 그래서 어떤 원형에서 일어나"안전한"같은 장소 속성 s 는 방법을 매개 변수를 반환 또는 유형입니다.

interface Interface<T> { val: T }
type X = Interface<X> // okay

class Class<T> { method(arg: T): void { } }
type Y = Class<Y> // okay

그러나 일반 형식 별칭 이 없다 이러한 보장합니다. 형식 별칭을 가질 수 있습하는 모든 구조에 어떤 익명 형식을 가질 수 있습니다,그래서 잠재적인 원형 제한되지 않습을 재귀 같은 나무 개체:

type Safe<T> = { val: T };
type Unsafe<T> = T | { val: string };

컴파일러 인스턴스화하는 일반적인 유형, 지연 그가 평가되지 않은 즉시 시도 완전히 계산 결과 유형입니다. 모두 보는 형태로 되어 있습니다.

type WouldBeSafe = Safe<WouldBeSafe>; 
type WouldBeUnsafe = Unsafe<WouldBeUnsafe>; 

두 사람의 동일하는 컴파일러는... type X = SomeGenericTypeAlias<X>. 할 수 없다"를 참조하십시오"그 WouldBeSafe 좋:

//type WouldBeSafe = { val: WouldBeSafe }; // would be okay

WouldBeUnsafe 문제가 될:

//type WouldBeUnsafe = WouldBeUnsafe | { val: string }; // would be error

이후 그것은 볼 수 없는 차이 때문에 적어도 일부 사용법을 것이 불법으로 원형에,그냥을 금지하 모니다.


그래서,당신은 무엇을 할 수 있습니까? 이것은 하나의 경우에는 내가 사용하는 것이 좋 interfacetype 할 수 있습니다. 다시 작성할 수 있습니다 record 유형(그것을 바꾸기 MyRecord 에 대한 이름 지정 규칙 이유)로 interface 고 모든 것이 해결됩니다:

interface MyRecord<T> { val: T };
type B = MyRecord<B>; // okay

할 수 있도 다시 작성 func 유형(그것을 바꾸기 Func 에 대한 이름 지정 규칙 이유 다)로 interface 을 변경하여 기능 유형 표현이 는 구문으로 호출 서명 syntax:

interface Func<T> { (arg: T): void }
type C = Func<C>; // okay

의 코스가있는 상황을 할 수 없는 바로,같은 내장 Record 유틸리티를 유형:

type Darn = Record<string, Darn>; // error

과할 수 없습니다 다시 쓰기 매핑된 형식 Recordinterface. 실제로,그것은 안전하지 않은 것을 만들려고 열쇠를 원형처럼, type NoGood = Record<NoGood, string>. 는 경우에만 하고 싶 Record<string, T> 일반 T할 수 있습 다시 쓰 는 것 으로 interface:

interface Dictionary<T> extends Record<string, T> { };
type Works = Dictionary<Works>;

그래서 거기에 자주 사용하는 방법입 interfacetype 을 표현할 수 있도록"안전한"재귀 종류.

놀이터에 대한 링크를 코드

2021-11-23 21:31:48

감사합니다! 이것은 멋진 도움이 됩니다!
radiish
1

자의 해부 이러한 시나리오의 중 하나에 의해 하나입니다.

대본 1

type a = { val: a }; // <-- doesn't care about circular references!

그것은 재미있는이 허용됩니다. 나는 보지 않는 방법 당신이 될 수 있을 만들 수 있는 인스턴스를 만족하는 이 유형:

const A: a = {
  val: {
    val: {
      // It will always error out at the most inner node.
    }
  }
}

시나리오 2

type record<T> = { val: T };

이 순환을 참조하고 만족할 수 있습니다 다음과 같다:

const B: record<string> = {
  val: "test"
}

시나리오 3

type b = record<b>; // <-- doesn't work!

그것은 나에게는 이 작동하지 않습니다. 에서 같은 시나리오 1,없을 것을 인스턴스를 만들어 이것을 만족하는 제약 조건이 있습니다.

시나리오 4

type func<T> = (arg: T) => void;

이 순환을 참조하고 만족할 수 있습니다 다음과 같다:

const C: func<string> = (arg: string) => {}

시나리오 5

type c = func<c>; // <-- doesn't work!

그것은 나에게는 이 작동하지 않습니다. 에서 같은 시나리오 1,없을 것을 인스턴스를 만들어 이것을 만족하는 제약 조건이 있습니다.

시나리오 6

type d = (arg: d) => void; // <-- works!?

내가 쓸 수 있는 실제 기능을 이 제약 조건을 만족하지만,저는 그것을 받고 내:

const D: d = (arg) => {}
D(D)
2021-11-23 21:34:19

다른 언어로

이 페이지는 다른 언어로되어 있습니다

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................