9

사양타이프 라이터 Array.prototype.map 선언

는 ... 같은

var new_array = arr.map(callback[, thisArg]) 

문제을 사용해야합니다

타이프 라이터에 대한 몇 가지 오버로드 선언을 가지고 지도, 그리고 이것은 매우 어렵습니다 extend Array<T>합니다.

나는이 을 (lib.d.ts에있는) 보여야하는데 ...

map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; 

그러나 이러한 ...

map<U>(this: [T, T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U, U]; 

map<U>(this: [T, T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U, U]; 

map<U>(this: [T, T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U, U]; 

map<U>(this: [T, T], callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): [U, U]; 
있다 lib.d.ts

이의 제기

JavaScript는 메소드 오버로드를 허용하지 않으며 클래스 구현을위한 TypeScript도 허용하지 않으므로 TypeScript가 앰비언트 선언을 위해 이것을 허용해야한다고 생각하십시오.

질문

  1. 왜 타이프 주변 선언에 대한 오버로드 서명을 할 수 있습니까?
  2. 배열을 확장하는 클래스에서지도 구현을 재정의하려면 어떻게해야합니까?
내가 너무 GitHub의에이 문제를 제기 한

... https://github.com/Microsoft/TypeScript/issues/13785

ReadonlyArray<T> 아니라지도에 대한 하나의 서명을 가지고 있습니다 ...

map<U>(callbackfn: (value: T, index: number, array: ReadonlyArray<T>) => U, thisArg?: any): U[]; 
+0

여기에서 IMO가 가장 중요한 측면에 대해 질문하지 않은 것은 흥미 롭습니다. _purpose_. * "왜 이러한 모든 오버로드 서명을 처음부터 정의해야합니까?"* - 그 대답은 TypeScript가 한정된 양의 배열을 가지는 타입 개념을 가지고 있다는 것입니다. 예를 들면'[number , number, number]'는 3 요소'number '이다. 이것은 _to_와 _ number_ [number]로부터 할당 가능하지만 컴파일러의 관점에서 볼 때 _precisely_와 동일하지 않습니다. 또한, 이들은 또한 몇몇 문맥에서 튜플 유형이라고 불리며, 꼭 필요하지 않은 inter-assignable elem 유형을 정의 할 수 있습니다. –

+0

@JohnWeisz n 요소 배열에 대한 개념을 알았지 만, 왜이 개념이 5 요소 배열에서 멈출까요? 확실하게 n은 무한 할 수 있습니까? – series0ne

답변

2

(1) 앰비언트 선언에서 서명에 과부하가 발생하지 않으면 어떻게 다른 서명을 얻을 수 있습니까? 네이티브 js 함수/메서드에서?
네이티브 js 개체의 작동 방식을 반영하는 오버로드가 lib.d.ts에 있습니다.

(2) 가능한 모든 서명을 포함하고 있음을 컴파일러에 알려줘야합니다.

class A<T> extends Array<T> { 
    map<U>(this: Array<U>, ...args: any[]); 
    map<U>(this: Array<T>, callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[] { 
     return []; 
    } 
} 

첫 번째 과부하 서명이 당신이 귀찮게하지 않으려는 사람을 담당 : 당신이 뭔가를 할 수있는 경우
.

1

귀하의 질문에 TypeScript의 다른 측면이 있습니다. 나는 그것들을 개별적으로 다룰 것이고 모두 함께 놓을 것이다.

배열 <T>

인터페이스는 타이프에서 이중 목적을 제공 :

  1. 그들은 당신이 구현하는 다른 (아직 존재하지 않는) 클래스 "true"로 인터페이스를 만들 수 있습니다. 인터페이스를 구현할 때 모든 멤버가 사용 가능하다는 보장이 있기 때문에이를 직접 구현해야합니다.
  2. 그들은 이미 존재하는 인터페이스를 정의 할 수 있습니다. 자바 스크립트 유형. 이것은 많은 기존 라이브러리 중 하나를 사용하고 정적 타이핑의 장점을 가지고 자 할 때 매우 유용합니다. 이러한 인터페이스는 보통 .d.ts 파일로 정의되며 파일에는 기본 JavaScript 유형이 포함 된 lib.d.ts 파일이 정의됩니다. 이러한 인터페이스는 기존 유형에 맞게 조정되며 일반적으로 구현할 수 없습니다. 원하는 경우 할 수 있지만 모든 멤버를 구현해야합니다.

Array<T> 인터페이스는 두 번째 종류이므로 구현할 수 없습니다. 기능

함수 정의의 this: 매개 변수

this 매개 변수는 인수를 전달할 수 있습니다 의미에서 실제 매개 변수가 아닙니다. 함수 본문에서 this 값이 될 것으로 예상되는 유형을 지정할 수 있습니다. 지정하지 않으면 thisany 유형이되며 대개는별로 유용하지 않습니다. 타이프에서

오버로드

기능/방법은, 기능 및 방법은 자바 나 C# 등의 언어로 오버로드 의미에서 과부하가되지 않습니다. 더 자주 구현할 수는 없지만 변형 유형을 반환하거나 변형 매개 변수를 사용하는 함수에 정적 유형 지정을 허용하는 대체 시그니처를 정의 할 수 있습니다. 특히 .d.ts 정의 파일에서는 기존 라이브러리가 JavaScript의 약한 유형 지정을 사용하여 값을 반환하거나 다른 유형의 매개 변수를 기대하기 때문에 유용하고 종종 필요합니다. 그것은 당신의 이의를 거짓으로 만듭니다. 이러한 JavaScript 구문을 수용하려면 함수 오버로드가 필요합니다. 자바 스크립트 배열에서

튜플

당신은 각 슬롯에 여러 유형의 값을 할당 할 수 있습니다. TypeScript 배열 정의에서 하나의 유형을 지정합니다.이 유형은 컴파일러에서 적용됩니다. 간격을 채우기 위해 튜플을 정의 할 수 있습니다. [number, string, string]과 같은 유형은 JavaScript 배열 any[]으로 변환되며 TypeScript는 여전히 정적 입력을 시행 할 수 있습니다.

요약

배열 방법은 당신이 정적 배열이 실제 [T, T], [T, T, T], [T, T, T, T], [T, T, T, T, T] 인 경우에 this 매개 변수를 입력 소개 Array<T>에 대해 반대 오버로드.배열이 다중 map 메서드를 제공한다는 것을 의미하지는 않습니다. 이것은 같은 메소드이지만 일부 특정 배열 유형에 대해 오버로드됩니다. lib.d.ts에서 제공되며 귀하가이를 구현하도록 설계되지 않았습니다. 기본 클래스를 확장 할 수는 있지만 (인터페이스가 없더라도 이미 존재 함) 오버로드로 인해 (적어도이 경우에는 this 매개 변수 만 제공되기 때문에) 해를 입히지 않습니다.

+1

'Array'는 실제로 확장 할 수있는 클래스입니다.이 대답을 게시하기 전에 확인 했어야합니다. 당신의 오랜 설명은 모두 OP에 알려져있을 것입니다 (그가 물었던 것과 그가 어떻게 질문했는지에 근거하여). –

+0

@NitzanTomer : (https://github.com/Microsoft/TypeScript/blob/master/lib/lib.d.ts - "인터페이스 배열 {")을 검색했는데 OP보다 더 잘 알고있는 것 같습니다. 나는한다. – Sefe

+0

'interface Array '뒤에 생성자를 정의하는'interface ArrayConstructor'가 있고'Array'를 클래스로 만드는'declare const Array : ArrayConstructor'가 있습니다. –