일반 함수의 Typscript ReturnType
새로운ReturnType
TypeScript 2.8은 특정 함수의 반환 유형을 추출할 수 있는 매우 유용한 기능입니다.
function foo(e: number): number {
return e;
}
type fooReturn = ReturnType<typeof foo>; // number
다만, 범용 기능에서는 사용하기 어렵습니다.
function foo<T>(e: T): T {
return e;
}
type fooReturn = ReturnType<typeof foo>; // type fooReturn = {}
type fooReturn = ReturnType<typeof foo<number>>; // syntax error
type fooReturn = ReturnType<(typeof foo)<number>>; // syntax error
일반 함수가 특정 유형 매개변수를 제공하는 반환 유형을 추출하는 방법이 있습니까?
이것은 Import된 라이브러리의 내보내기되지 않은 내부 타입(knex 등)을 추출하기 위해 현재 동작하고 있는 솔루션입니다.
// foo is an imported function that I have no control over
function foo<T>(e: T): InternalType<T> {
return e;
}
class Wrapper<T> {
// wrapped has no explicit return type so we can infer it
wrapped(e: T) {
return foo<T>(e)
}
}
type FooInternalType<T> = ReturnType<Wrapper<T>['wrapped']>
type Y = FooInternalType<number>
// Y === InternalType<number>
이것은 이전에는 완전히 일반적인 방식으로는 불가능했지만, Typescript 4.7에 포함될 것이다.이 패턴을 인스턴스 표현이라고 합니다.관련 PR은 이쪽입니다.설명에서 발췌:
function makeBox<T>(value: T) { return { value }; }; const makeStringBox = makeBox<string>; // (value: string) => { value: string } const stringBox = makeStringBox('abc'); // { value: string } const ErrorMap = Map<string, Error>; // new () => Map<string, Error> const errorMap = new ErrorMap(); // Map<string, Error> ```
...
특히 유용한 패턴은 다음 어플리케이션의 범용 타입 에일리어스를 작성하는 것입니다.
typeof
유형 인스턴스화 식에서 참조 유형 매개 변수:type BoxFunc<T> = typeof makeBox<T>; // (value: T) => { value: T } type Box<T> = ReturnType<typeof makeBox<T>>; // { value: T } type StringBox = Box<string>; // { value: string }
특수한 범용 타입을 취득하고 싶은 경우는, fake 함수를 사용해 랩 할 수 있습니다.
const wrapperFoo = () => foo<number>()
type Return = ReturnType<typeof wrapperFoo>
보다 복잡한 데모
function getList<T>(): {
list: T[],
add: (v: T) => void,
remove: (v: T) => void,
// ...blahblah
}
const wrapperGetList = () => getList<number>()
type List = ReturnType<typeof wrapperGetList>
// List = {list: number[], add: (v: number) => void, remove: (v: number) => void, ...blahblah}
함수의 정의를 변경할 수 있으면, 이것을 실현하기 위한 간단하고 좋은 방법을 찾았습니다.제 경우, 저는 타이프스크립트 타입을 사용해야 했습니다.Parameters
일반적인 기능을 가진, 정확히 말하면Parameters<typeof foo<T>>
그리고 효과적으로 작동하지 않습니다.따라서 이를 실현하는 가장 좋은 방법은 인터페이스 함수 정의에 의해 함수 정의를 변경하는 것입니다.이것은 typescript 타입에서도 동작합니다.ReturnType
.
다음은 OP에 의해 설명되는 대소문자에 이은 예입니다.
function foo<T>(e: T): T {
return e;
}
type fooReturn = ReturnType<typeof foo<number>>; // Damn! it throws error
// BUT if you try defining your function as an interface like this:
interface foo<T>{
(e: T): T
}
type fooReturn = ReturnType<foo<number>> //it's number, It works!!!
type fooParams = Parameters<foo<string>> //it also works!! it is [string]
//and you can use the interface in this way
const myfoo: foo<number> = (asd: number) => {
return asd;
};
myfoo(7);
해결책을 찾았어요고객의 요구에 적합한지 여부를 판단합니다.
인터페이스를 사용하여 함수 arg를 선언하고 유형을 반환합니다.
interface Foo<T, V> {
(t: T, v: V): [T, V]
}
다음과 같은 방법으로 기능을 구현합니다.Parameters
그리고.ReturnType
function foo<T, V>(...[t, v]: Parameters<Foo<T, V>>): ReturnType<Foo<T, V>> {
return [t, v]; // [T, V]
}
정상적으로 영업 담당자에게 전화를 걸거나 다음을 사용하여 반품 유형을 가져옵니다.ReturnType
foo(1, 'a') // [number, string]
type Test = ReturnType<Foo<number, number>> // [number, number]
const wrapperFoo = (process.env.NODE_ENV === 'typescript_helper' ? foo<number>(1) : undefined)!
type Return = typeof wrapperFoo
다음은 내보낼 수 없는 기본 유형이 있는 다른 사용 사례입니다.
// Not exported
interface Unaccessible1 {
z: number
x: string
}
function foo1<T extends Unaccessible1>(e: T): T {
return e;
}
const wrapperFoo1 = (process.env.NODE_ENV === 'typescript_helper' ? foo1.apply(0, 0 as any) : undefined)!
type ReturnFoo1 = typeof wrapperFoo1 // Unaccessible1
interface Unaccessible2 {
y: number
c: string
}
function foo2<T extends Unaccessible2>(e: T, arg2: number, arg3: string, arg4: Function): T {
return e;
}
const wrapperFoo2 = (process.env.NODE_ENV === 'typescript_helper' ? foo2.apply(0, 0 as any) : undefined)!
type ReturnFoo2 = typeof wrapperFoo2 // Unaccessible2
TypeScript 컴파일러가 표시되지 않음typeof foo
범용 타입으로 합니다.컴파일러에 오류가 있는 것 같습니다.
단, TypeScript에는 문제없이 범용적인 콜 가능 인터페이스가 있기 때문에 함수의 시그니처와 호환되는 콜 가능 인터페이스를 도입하면 다음과 같은 독자적인 인터페이스를 구현할 수 있습니다.ReturnType
다음과 같습니다.
function foo<T>(x: T): T {
return x;
}
interface Callable<R> {
(...args: any[]): R;
}
type GenericReturnType<R, X> = X extends Callable<R> ? R : never;
type N = GenericReturnType<number, typeof foo>; // number
언급URL : https://stackoverflow.com/questions/50321419/typescript-returntype-of-generic-function
'programing' 카테고리의 다른 글
오류: [$injector:unpr] 알 수 없는 공급자: Angular입니다.JS 서비스 테스트 (0) | 2023.02.22 |
---|---|
Wordpress - slug별로 태그 ID 가져오기 (0) | 2023.02.22 |
스프링 부트: 2개의 데이터 소스 구성 및 사용 (0) | 2023.02.22 |
AngularJs 문자열의 첫 글자를 대문자로 표시 (0) | 2023.02.22 |
JavaScript를 사용하는 AJAX와 jQuery의 차이점은 무엇입니까? (0) | 2023.02.22 |