programing

함수의 반환 유형 가져오기

megabox 2023. 3. 25. 10:59
반응형

함수의 반환 유형 가져오기

다음과 같은 기능이 있습니다.

function test(): number {
    return 42;
}

를 사용하여 함수의 종류를 얻을 수 있습니다.typeof:

type t = typeof test;

여기서,t될 것이다() => number.

함수의 반환 타입을 얻을 수 있는 방법이 있습니까?하고 싶다t되려고number대신() => number.

편집

이것은 TypeScript 2.8에서 공식적으로 가능합니다.ReturnType<T>.

type T10 = ReturnType<() => string>;  // string
type T11 = ReturnType<(s: string) => void>;  // void
type T12 = ReturnType<(<T>() => T)>;  // {}
type T13 = ReturnType<(<T extends U, U extends number[]>() => T)>;  // number[]

자세한 내용은 Microsoft/TypeScript에 대한 이 풀 요청을 참조하십시오.

Type Script는 멋져요!


구식 해킹

안타깝게도 라이언의 대답은 더 이상 통하지 않는다.하지만 나는 터무니없이 만족스러운 해킹으로 그것을 수정했다.보기:

const fnReturnType = (false as true) && fn();

캐스팅으로 작업합니다.false문자 그대로의 가치로true따라서 유형 시스템에서는 반환값이 함수의 유형이라고 생각되지만 실제로 코드를 실행하면 단락이 발생합니다.false.

TypeScript 2.8에서 가장 쉬운 방법:

const foo = (): FooReturnType => {
}

type returnType = ReturnType<typeof foo>;
// returnType = FooReturnType

빌트인 사용ReturnType:

type SomeType = ReturnType<typeof SomeFunc>

ReturnType확장 대상:

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

다음 코드는 함수를 실행하지 않아도 작동합니다.react-byplex-typescript 라이브러리(https://github.com/alexzywiak/react-redux-typescript/blob/master/utils/redux/typeUtils.ts)에서 가져옵니다.

interface Func<T> {
    ([...args]: any, args2?: any): T;
}
export function returnType<T>(func: Func<T>) {
    return {} as T;
}


function mapDispatchToProps(dispatch: RootDispatch, props:OwnProps) {
  return {
    onFinished() {
      dispatch(action(props.id));
    }
  }
}

const dispatchGeneric = returnType(mapDispatchToProps);
type DispatchProps = typeof dispatchGeneric;

이 방법은 없습니다(작업 항목 추적에 대해서는 https://github.com/Microsoft/TypeScript/issues/6606를 참조하십시오).

일반적인 회피책은 다음과 같습니다.

var dummy = false && test();
type t2 = typeof dummy;

편집:TS 2.8에서는 더 이상 필요하지 않습니다. ReturnType<F>는 반환 유형을 제공합니다.승인된 답변을 참조하십시오.


내가 사용하고 있는 몇 가지 이전 답변에 대한 변형으로, 이는 에서 작동합니다.strictNullChecks추론 체조를 약간 숨깁니다.

function getReturnType<R>(fn: (...args: any[]) => R): R {
  return {} as R;
}

사용방법:

function foo() {
  return {
    name: "",
    bar(s: string) { // doesn't have to be shorthand, could be `bar: barFn` 
      return 123;
    }
  }
}

const _fooReturnType = getReturnType(foo);
export type Foo = typeof _fooReturnType; // type Foo = { name: string; bar(s: string): number; }

명령어는getReturnType원래 함수는 호출하지 않습니다.예방할 수 있습니다.getReturnType를 사용하여 호출하다(false as true) && getReturnType(foo)IMO는 더 헷갈리게 만들어요.

저는 이 방법을 regexp find/replace와 함께 사용하여 원래 JS에서 1500개까지의 공장 함수를 가진 오래된 Angular 1.x 프로젝트를 마이그레이션하고, 추가했습니다.Foo모든 용도에 대한 etc 유형...깨진 암호를 찾아내는 건 정말 놀라운 일이야:)

해당 함수가 사용자 정의 클래스의 메서드인 경우 메서드 디코레이터Reflect Metadata와 함께 사용하여 런타임에 반환 유형(컨스트럭터 함수)을 결정할 수 있습니다.

예를 들어 콘솔에 기록할 수 있습니다.

function logReturnType(
    target: Object | Function,
    key: string,
    descriptor: PropertyDescriptor
): PropertyDescriptor | void {
    var returnType = Reflect.getMetadata("design:returntype", target, key);

    console.log(returnType);
}

이 메서드 데코레이터를 선택한 메서드로 스냅하면 메서드 호출에서 반환되는 객체의 컨스트럭터 함수에 대한 정확한 참조를 얻을 수 있습니다.

class TestClass {
    @logReturnType // logs Number (a string representation)
    public test(): number {
        return 42;
    }
}

단, 이 접근법에는 몇 가지 주목할 만한 제한이 있습니다.

  • 유형이 그렇지 않으면 다음에서 정의되지 않습니다.Reflect.getMetadata ,
  • 컴파일 후에 존재하는 실제 유형만 참조할 수 있습니다.즉, 인터페이스나 제네릭은 없습니다.

또한 이 게시물을 작성하는 시점에서는 데코레이터와 리플렉트 메타데이터가 모두 실험적인 기능이기 때문에 typscript 컴파일러에 대해 다음 명령줄 인수를 지정해야 합니다.

--emitDecoratorMetadata --experimentalDecorators

저는 다음과 같은 것을 생각해 냈습니다만, 효과가 있는 것 같습니다.

function returnType<A, B, Z>(fn: (a: A, b: B) => Z): Z
function returnType<A, Z>(fn: (a: A) => Z): Z
function returnType<Z>(fn: () => Z): Z
function returnType(): any {
    throw "Nooooo"
}

function complicated(value: number): { kind: 'complicated', value: number } {
    return { kind: 'complicated', value: value }
}

const dummy = (false as true) && returnType(complicated)
type Z = typeof dummy

언급URL : https://stackoverflow.com/questions/36015691/obtaining-the-return-type-of-a-function

반응형