如何使用Typescript正确设置这些类型?

时间:2018-03-16 16:54:40

标签: javascript typescript

我怎么能用打字稿来写这个?

所以我有一个类型Status,它有三个属性:name,actionName和style。我还有一个常量statusTypes,它有两个Status类型的属性。

这是我到目前为止所做的,但它不起作用。我收到此错误[ts] Type '{ Active: any; Inactive: any; }' is not assignable to type 'Status[]'. Object literal may only specify known properties, and 'Active' does not exist in type 'Status[]'

export interface Status {
  name: string;
  actionName: string;
  style: string;
}

export const statusTypes: Status[] = {
  Active : {
    name: "Active",
    actionName: "Deactivate",
    style: "success"
  },
  Inactive : {
    name: "Inactive",
    actionName: "Activate",
    style: "warning"
  }
};

4 个答案:

答案 0 :(得分:2)

问题

您正在尝试将对象分配给Status数组。

解决方案

以下列出了您的一些选项。您可以自行决定在设计中最有效的方法:

选项1:数组

export const statusTypes: Status[] = [{
    name: "Active",
    actionName: "Deactivate",
    style: "success"
  }, {
    name: "Inactive",
    actionName: "Activate",
    style: "warning"
  }
];

选项2:索引签名

export const statusTypes: {[key: string]: Status} = {
  active: {
    name: "Active",
    actionName: "Deactivate",
    style: "success"
  }, 
  inactive: {
    name: "Inactive",
    actionName: "Activate",
    style: "warning"
  }
};

选项3:接口

interface StatusTypes {
  active: Status;
  inactive: Status;
}

export const statusTypes: StatusTypes = {
  active: {
    name: "Active",
    actionName: "Deactivate",
    style: "success"
  }, 
  inactive: {
    name: "Inactive",
    actionName: "Activate",
    style: "warning"
  }
};

答案 1 :(得分:2)

数组中的项目不能有名称。

您可以创建一个简单的数组。

export const statusTypes: Status[] = [
    {
        name: "Active",
        actionName: "Deactivate",
        style: "success"
    },
    {
        name: "Inactive",
        actionName: "Activate",
        style: "warning"
    }
];     

或创建一个对象,让编译器推断出它的类型:

export const statusTypes = {
    Active: {
        name: "Active",
        actionName: "Deactivate",
        style: "success"
    },
    Inactive: {
        name: "Inactive",
        actionName: "Activate",
        style: "warning"
    }
};

或者,如果要确保属性的正确类型,可以定义辅助函数:

function defineStatuses<T extends { [name: string]: Status }>(o: T) {
    return o
}

export const statusTypes = defineStatuses({
    Active: {
        name: "Active",
        actionName: "Deactivate",
        style: "success"
    },
    Inactive: {
        name: "Inactive",
        actionName: "Activate",
        style: "warning"
    }
});

最后一种方法是我推荐的方法,你有完整的类型安全性,因为编译器会在忘记或添加Status的属性时警告你,没有额外的接口要维护,你可以使用已定义的属性(如作为Active / Inactive)代替[string]

答案 2 :(得分:2)

正如其他人所提到的,问题在于它是一个数组:

如果那是你想要的架构,你应该这样做:

interface StatusTypes {
 Active: Status;
 Inactive: Status
}

export interface Status {
  name: string;
  actionName: string;
  style: string;
}

export const statusTypes: StatusTypes = {
  Active : {
    name: "Active",
    actionName: "Deactivate",
    style: "success"
  },
  Inactive : {
    name: "Inactive",
    actionName: "Activate",
    style: "warning"
  }
};

TS Playground

上查看

每当你想拥有带密钥的对象时,正确的方法是创建接口,每个接口都应该有一个属性,它将成为对象的密钥。

英文:

通过为对象StatusTypes分配对象,您告诉它它是一个对象ActiveInactive个键,其形状符合{{1}接口。如果您要向Status添加其他密钥,请将其添加到const statusTypes界面。如果有一个您不希望指定的密钥,请附加&#34;?&#34;在酒店的尽头:

StatusTypes

答案 3 :(得分:1)

在玩了一下之后,我想出了我需要的东西:

export interface Status {
  name: string;
  actionName: string;
  style: string;
}

export const statusTypes = {
  Active : <Status> {
    name: "Active",
    actionName: "Deactivate",
    style: "success"
  },
  Inactive : <Status> {
    name: "Inactive",
    actionName: "Activate",
    style: "warning"
  }
};