TypeScript 범주를 이해하는 방법

5571 단어 ts범용

개요


TypeScript에서는 범주를 사용하여 함수의 관련 유형을 구속합니다.이곳의 함수는class의 구조 함수를 포함하기 때문에 한 종류의 성명 부분도 범용형을 사용할 수 있다.그렇다면 도대체 무엇이 일반적인가?만약 통속적인 이해가 일반적이라면?

범용


일반(Generics)은 함수, 인터페이스, 클래스를 정의할 때 구체적인 유형을 미리 지정하지 않고 사용할 때 유형을 지정하는 특성을 말한다.
통속적인 해석에 의하면 범형은 유형 시스템의'매개 변수'로 주요 역할은 유형의 중용을 위한 것이다.위의 정의를 보면 함수, 인터페이스, 클래스에만 사용된다는 것을 알 수 있다.이것은 js 프로그램의 함수 매개 변수와 두 차원의 사물(의미는 같지만)이다. typescript는 정적 형식 시스템이고 js가 컴파일할 때 형식 검사를 하는 시스템이기 때문에 범용 이런 매개 변수는 실제로 컴파일 과정에서 실행될 때 사용된다.이것을 매개 변수라고 부르는 이유는 함수 매개 변수와 똑같은 특성을 가지고 있기 때문이다.

function increse(param) {
  // ...
}
유형 시스템에서는 다음과 같은 범주를 사용합니다.

function increase<T>(param: T): T {
  //...
}
파라미터가 하나의 유형일 때, T는 이 유형으로 부여되고, 반환값에서 T는 이 유형으로 분류되어 유형 검사를 합니다.

컴파일링 시스템


typescript 자체의 유형 시스템도 프로그래밍이 필요하다는 것을 알아야 한다. 그러나 프로그래밍 방식이 이상하다. 프로그램 코드에 js 코드를 삽입해야 한다. (ts 코드에 js 코드를 삽입한다는 말은 이상하다. 왜냐하면 우리의 직관적인 느낌은 js 코드에 ts 코드가 섞여 있기 때문이다.)
프로그래밍에서 가장 중요한 형식은 함수다.typescript의 형식 프로그래밍에서 함수를 보았습니까?아니요.이것은 범용적인 곳에 함수가 있기 때문에 함수의 형식이 js 코드에 의해 갈라졌기 때문이다.typescript는 컴파일해서 최종 산물을 얻어야 합니다.컴파일하는 과정에서 두 가지 일을 해야 한다. 하나는 메모리에서 유형 프로그래밍을 실행하는 코드로 유형 검사 체계를 형성하는 것이다. 즉, 우리는 js 코드에 대해 유형 검사를 할 수 있다. 첫째, typescript 컴파일러가 ts프로그래밍 코드를 실행한 후에 실행할 때의 검사 시스템을 얻었다. 본고는 부자고의 팟캐스트에서 나온 것으로 이 시스템을 실행하여 그 안에 삽입된 js 코드에 대해 유형 단언을 한다.둘째, js를 출력하는 과정에서 컴파일링 시스템은 유형 프로그래밍 코드를 실행했다. php 코드에서echo js 코드처럼 php 코드가 실행되었고 표시된 것은 js 코드이다.
이 각도에서 볼 때 typescript는 왜 자바스크립트의 초집합이라고 말하는지, 왜 그 번역 결과가 js인지 이해할 수 있을 것이다.

통속적 이해 범형


기왕 우리가 ts컴파일링 시스템의 논리를 이해한 이상 우리는 유형의 프로그래밍과 js 자체의 업무 프로그래밍을 감정적으로 구분할 수 있다.우리가 말하는'범용'은 유형 프로그래밍 부분에만 존재하고 이 부분 코드는ts의 컴파일이 실행될 때 코드입니다.
다음 간단한 예를 살펴보겠습니다.

function increase<T>(param: T): T {
  //...
}
이 코드, 만약 우리가 js 코드를 구분한 후에 유형 설명 텍스트로 표시하면 어떻게 됩니까?

//   @type,  T,  (T): T 
@type = T => (T): T

//   F,  (number): number
@F = @type(number)

//   increase   F  ,  number,  number 
@@F
function increase(param) { 
  // ... 
} 
@@end
실제로 @@F라는 문법은 없습니다. 제가 지어낸 것입니다. 다른 각도에서 유형 시스템을 볼 수 있도록 하기 위해서입니다.
우리가 범주형이 일종의'매개 변수'라는 것을 이해한 후에 우리는 유형 시스템의 함수가 어디에 있느냐고 물어볼 수 있다.js 함수에 대해 말하자면, 함수 성명 문장과 파라미터를 쉽게 지적할 수 있지만,ts에서 이 부분은 숨겨져 있다.그러나 우리는 특정한 구조에서 유형 함수의 그림자를 비교적 쉽게 볼 수 있다.

//  , , ,  @type = T => (T): T
interface GenericIdentityFn<T> {
    (arg: T): T;
}

//  , , , , :@@[T => (T): T](any)
function identity<T>(arg: T): T {
    return arg;
}

//  , ,  @type(number)
let myIdentity: GenericIdentityFn<number> = identity;
위의 전체 코드를 우리는 설명 텍스트로 다시 한 번 쓴다.

@GenericIdentityFn = T => (T): T

@@[T => (T): T](any)
function identify(arg) {
  return arg
}
@@end

@@GenericIdentityFn(number)
let myIdentity = identity
@@end
형식 시스템에서 @GenericIdentityFn과 @some (익명 함수 @[T=>(T): T]) 두 함수를 설명했습니다.두 함수이지만 실제로는 똑같습니다. typescript는 구조 유형이기 때문입니다. 즉, 유형 검사를 할 때 구조상의 각 노드 유형이 같은지 아닌지만 판단하고 유형 변수 자체의 바늘을 동일하게 유지해야 하기 때문입니다. @Generic Identity Fn과 @some 두 함수는 각각 호출되어 identify와 my Identify를 수식하는데 사용되며, 호출할 때 수신하는 매개 변수가 다르기 때문에 최종 형식 검사 규칙이 다르다. identify는 매개 변수와 반환 값의 유형이 같고 구체적인 어떤 유형에 대해any를 보장한다.myIdentify는 매개 변수의 반환 값 형식이 같다는 것을 보장하는 것 외에 형식은number이어야 한다고 요구합니다.

범형류


범용 인터페이스를 제외하고class류도 범형화할 수 있다. 즉'범형류'이다. 범형류를 빌려 우리는 범형의 성명과 사용 절차를 탐구한다.

class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
앞의 범용 인터페이스는 함수의 유형을 제약하기 위한 것이기 때문에 함수와 매우 비슷하게 썼다. 실제로 우리는 묘사 언어로 범용 인터페이스와 범용 클래스를 다시 묘사할 수 있다.위의 빨간색 부분에서 우리는 묘사 언어로 묘사한다.

@GenericNumber = T => class {
  zeroValue: T;
  add: (x: T, y: T) => T;
}
@Generic Number라는 함수는 T를 매개 변수로 하고class를 되돌려줍니다. @type 함수 안에서 매개 변수 T를 여러 번 사용했습니다.

@GenericIdentityFn = T => interface { 
  (arg: T): T; 
}
우리는 인터페이스에 다른 방법을 추가할 수 있도록 앞의 인터페이스 Generic Identity Fn을 다시 설명했습니다.
typescript에 내장된 기본 유형, 예를 들어 Array가 범용 인터페이스, 범용 클래스로 선언된 후에도 이러한 인터페이스와 클래스는 사용할 때 <>를 통해 매개 변수를 전달해야 한다는 것을 알 수 있습니다. 본질적으로는 함수이기 때문에 반환값만 다르기 때문입니다.

기타 범용 사용의 통속적 해석


다음은 복잡한 유형을 설명하고자 합니다.

class Animal {
    numLegs: number;
}

function createInstance<A extends Animal>(c: new () => A): A {
    return new c();
}
우리는 당분간 new()의 부분을 보지 않을 것이다. 우리는 뾰족한 괄호 중의 extends 문법을 본다. 여기서 어떻게 이해해야 합니까?실제로 우리가 직면한 문제는 컴파일할 때 뾰족한 괄호 안의 내용이 언제 실행되었는가, 이전인가, 사이인가? // 도대체 @type = (A extends Animal) => (new() => A): A @type(T) // 아니면 @type = A => (new() => A): A @type (T extends Animal) 잘 지내다. @type = (A extends Animal) => (new() => A): A즉, @type(T)을 사용하여 유형을 생성하려면 먼저 T가 애니멀의 구조를 만족시켜야 필요한 유형을 얻을 수 있다. 만약에 T가 애니멀류의 구조를 만족시키지 못하면 컴파일러가 직접 오류를 보고한다. 이 오류는 유형 검사 단계가 아니라 유형 시스템의 생성 단계, 즉ts 코드의 운행 단계이다.이런 상황을'범용 구속'이라고 부른다.또한 와 같은 문법은 사실 함수 매개 변수와 일치한다. @type = (A, B) => (A|B): SomeTypets에 내장된 기본 유형: Array @Array=any=>any[] 결어 Typescript 의 해석 은 사실 의 해석 이다.본고의 내용은 모두 근거 없는 상상으로 ts를 이해할 때의 사고방식 개척에만 적용되고 실제 프로그래밍에는 적용되지 않는다고 성명합니다.다음은 TypeScript 범주를 어떻게 통속적으로 해석하는지에 대한 상세한 내용입니다. 더 많은 TypeScript 범주에 관한 자료는 저희 다른 관련 글을 주목해 주십시오!

좋은 웹페이지 즐겨찾기