我将如何构造类型来表示呢?

时间:2019-11-05 16:08:41

标签: typescript typescript-typings

假设我有一个界面

interface FooBranchState {
  a: string;
  b: FooDiscriminator;
}

type FooDiscriminator = (value: any) => FooState;

我想将FooState定义为代表以下类型的类型或接口:

  • SingleFooBranchStateImpl的实例
  • SingleFooBranchStateImpl的实例数组

还有

  • 返回上述任何一个的函数
  • 向上述任何一项返回承诺的函数

我目前有


export type FooState = FooEndState | FooBranchState

export type FooDiscriminator = (value: any) => FooState;

export type FooEndState = null;

export type FooBranchState = SingleFooBranchState | (SingleFooBranchState[])

export interface SingleFooBranchStateImpl {
  foo: any;
  next: FooDiscriminator;
}

export type SingleFooBranchStateFunction = () => SingleFooBranchStateImpl 
export type SingleFooBranchState = SingleFooBranchStateImpl | SingleFooBranchStateFunction;


function test(value: FooState) {
  console.log(value);
}

function getSingle(): FooState {
  return { 
    foo: 1,
    next: () => null
  };
}

function getNull(): FooState {
  return null;
}


function getArray(): FooState {
  return [
    getSingle(),
    getSingle()
  ];
}

function getFunctionSingle(): FooState {
  return () => ({
    foo: 2,
    next: () => null
  });
}

function getFunctionArray(): FooState {
  return () => ([{
    foo: 3,
    next: () => null
  }]);
}

function getPromise(): FooState {
  return Promise.resolve({
    foo: 4,
    next: () => null
  });
}

但是将FooState[]分配给FooState需要强制转换为FooState,否则会出现以下错误。这使我认为我的定义有误。

错误是:

  

类型'FooBranchState []'无法分配给类型'FooBranchState'。     类型“ FooBranchState []”不可分配给类型“ SingleFooBranchState []”。       类型“ FooBranchState”不可分配给类型“ SingleFooBranchState”。         类型“ SingleFooBranchState []”不可分配给类型“ SingleFooBranchState”。           类型“ SingleFooBranchState []”不可分配给类型“ SingleFooBranchStateFunction”。             类型“ SingleFooBranchState []”与签名“():SingleFooBranchStateImpl”不匹配。

编辑: 更正了原始问题中的一些拼写错误(我将我的实际代码简化为一个简短的示例,并犯了一些错误)。

根据要求,下面是一个示例:https://stackblitz.com/edit/typescript-xyag2s

edit2: 基于对此的一些评论,我更加努力地考虑了这一点,并提出了一个更简化的示例: http://www.typescriptlang.org/play/?ssl=1&ssc=1&pln=18&pc=1#code/C4TwDgpgBAogtmUUC8UB2BXANlg3AWAChRIoANAJhSgGdgAnASzQHMDjxozrKoAfchQDaAXX6wEodkSIAzDGgDGwRgHs0UFhGABlZiywQAFAEoAXOSgBvKAHpbUAO6r6AaxpEoUetoz0NAOQAFowB7AC+MoTySirqmtoActhYphbcNvZOLu6e3r7+6CkRUTHKahpawACC9PQAhiBpljZ2DhB1LgA0UABGEIr1GDRcUIMa-UU4Pb0YwIJj9WgB85OYOHk+wH4aQl77B4deWdzjfdBLUPV1jVCqsoIzc1caZKLZ2AAmV1g0qmPqYD1Zh5LxVPSsQymI6HLJ7dZYHoBOhMVgBKAiPIiEqEOQKcrxKq1BogCjNDJtbJuDyELxbHZQIQrCB0ALYojhIA

type Empty = null;
type X2 = string;
type X = X2 | X2[] | Empty;


function getSingle(): X { // works
  return 'hi';
}

function getNull(): X { // works
  return null;
}

function getArray(): X {  // error, because X can be null, but X2 can't be null
  return [                // X can be an array of X2, but an X[] would also contain
    getSingle()           // [ null, 'string' ]
  ];
}

function getArray2(): X { // works
  return ['test'];
}

在简单的示例中,将getSingle声明为X2几乎是有意义的,但是出于我的实际需要,我需要能够从同一个函数返回多个变体。

1 个答案:

答案 0 :(得分:1)

可能是这样的:

export type Foo = any;

export type FooState = null | Foo | Array<Foo> | FooDistriminator | FooDistriminatorPromise;

export type FooDistriminator = (value: any) => null | Foo | Array<Foo>;

export type FooDistriminatorPromise = (value: any) => Promise<null | Foo | Array<Foo>>;

编辑:在您的堆栈闪电问题中,问题似乎出在传递输入值和返回值的函数类型上。我的工作方式是:

export type FooState = FooEndState | FooBranchState

export type FooDiscriminator = (value: any) => FooState;

export type FooEndState = null;

export type FooBranchState = SingleFooBranchState | Array<SingleFooBranchState> | Promise<SingleFooBranchStateImpl>

export interface SingleFooBranchStateImpl {
    foo: any;
    next: FooDiscriminator;
}

export type SingleFooBranchStateFunction = () => SingleFooBranchStateImpl
export type SingleFooBranchState = SingleFooBranchStateImpl | SingleFooBranchStateFunction;


function test(value: FooState) {
    console.log(value);
}

function getSingle(): SingleFooBranchStateImpl {
    return {
        foo: 1,
        next: () => null
    };
}

function getNull(): FooState {
    return null;
}


function getArray(): Array<SingleFooBranchState> {
    return [
        getSingle(),
        getSingle()
    ];
}

function getFunctionSingle(): FooState {
    return () => ({
        foo: 2,
        next: () => null
    });
}


function getPromise(): Promise<SingleFooBranchStateImpl> {
    return Promise.resolve({
        foo: 4,
        next: () => null
    });
}

test(null);
test(getSingle());
test(getNull());
test(getArray());
test(getFunctionSingle());
test(getPromise());