typescript 从初始参数接口约束顺序方法调用

mm9b1k5b  于 2023-01-27  发布在  TypeScript
关注(0)|答案(1)|浏览(179)

我正在尝试创建一个运行时API,它的作用也类似于类型Assert,因为传递的两个组件必须是对同一形状的泛型。
这会不断失败,并出现如下错误,这是合理的:

Argument of type 'typeof A' is not assignable to parameter of type 'Component<any>'.
  Property '[S]' is missing in type 'typeof A' but required in type 'Component<any>'.

但我不知道该如何实现我的梦想。
Playground

import {expectTypeOf} from 'expect-type';

declare const S: unique symbol;

declare class Component<S> {
  declare private [S]: S;
}

type InferSignature<T> = T extends Component<infer Signature> ? Signature : never;

declare class A extends Component<{
  name: string;
  age: number;
}> {};

declare class B extends Component<{
  mismatch: true
}> {}

function fromThis<T extends Component<any>>(ThisComponent: T) {
  return {
    toThat<R extends Component<InferSignature<T>>>(ThatComponent: R) {
      return {
        withRuntimeTest( testName: string) {
          if (window.location.search.includes(testName)) {
            return ThatComponent;
          }

          return ThisComponent;
        }
      }
    }
  }
}

// Properly infers
type ASig = InferSignature<A>;
// Also propertly infers
type BSig = InferSignature<B>;

// This the type of behavior I'm looking for
expectTypeOf<ASig>().toEqualTypeOf(BSig)

// This does not work like expectTypeOf
fromThis(A).toThat(B).withRuntimeTest('my-b-test')
z0qdvdin

z0qdvdin1#

这是我想出来的。

declare const S: unique symbol;

declare class Component<S> {
  declare private [S]: S;
}

declare class A extends Component<{
  name: string;
  age: number;
}> {};

declare class B extends Component<{
  mismatch: true
}> {}

type Ctor<T> = abstract new (...args: any[]) => T;
type ComponentCtor =  Ctor<Component<any>>;

function fromThis<T extends ComponentCtor>(ThisComponent: T) {
  return {
    toThat
    (ThatComponent: Ctor<InstanceType<T>>) {
      return {
        withRuntimeTest(testName: string) {
          if (window.location.search.includes(testName)) {
            return ThatComponent;
          }

          return ThisComponent;
        }
      }
    }
  }
}

fromThis(A).toThat(B).withRuntimeTest('my-b-test')

相关问题