如何从对象初始化关联数组?

How to initialize an associative array from an object?

给定

 this.themes = [
    {
       name: 'Material Teal', 
       colors: {
          'primary': { default: [ 0,  150, 136], a100: [167, 255, 237], a200: [100, 255, 218], a400: [ 29, 233, 182], a700: [  0, 191, 165] },
          'accent' : { default: [103,  58, 183], a100: [179, 136, 255], a200: [124,  77, 255], a400: [101,  31, 255], a700: [ 98,   0, 234] },
          'warn'   : { default: [244,  67,  54], a100: [255, 138, 128], a200: [255,  82,  82], a400: [255,  23,  68], a700: [213,   0,   0] }
       }
    },
    ...
];

export class Theme {
   name: string;
   colors: { [intention: string]: { default: number[], a100: number[], a200: number[], a400: number[], a700: number[] } };
   constructor(name: string, colors: { [intention: string]: { default: number[], a100: number[], a200: number[], a400: number[], a700: number[] } }) {
      this.name = name;
      this.colors = colors;
   }
   ...
}

如何传入对象的 colors 部分?我以为

let theme = new Theme(theme.name, theme.colors);

可以解决问题,但这给了我一个错误:

[ts] Argument of type '{ 'primary': { default: number[]; a100: number[]; a200: number[]; a400: number[]; a700: number[];...' is not assignable to parameter of type '{ [intention: string]: { default: number[]; a100: number[]; a200: number[]; a400: number[]; a700:...'.

Index signature is missing in type '{ 'primary': { default: number[]; a100: number[]; a200: number[]; a400: number[]; a700: number[];...'.

什么是索引签名,我可以用它做什么?

尝试用 'primary' 替换 [intention: string],像这样:

export class Theme {
   name: string;
   colors: { 'primary': { default: number[], a100: number[], a200: number[], a400: number[], a700: number[] } };
   constructor(name: string, colors: { 'primary': { default: number[], a100: number[], a200: number[], a400: number[], a700: number[] } }) {
      this.name = name;
      this.colors = colors;
   }
   ...
}

并且警告!您正在使用 let 运算符定义 theme,但此变量已存在!

发生这种情况是因为编译器不理解 this.themes 属于以下类型:

{
    name: string;
    colors: { [name: string]: {
        default: number[];
        a100: number[];
        a200: number[];
        a400: number[];
        a700: number[];
    }
}

你需要做的就是指定类型,所以像这样:

interface ThemeColor {
    default: number[];
    a100: number[];
    a200: number[];
    a400: number[];
    a700: number[];
}

interface ThemeColors {
    [name: string]: ThemeColor;
}

interface Theme {
    name: string;
    colors: ThemeColors;
}

let themes: Theme[] = [
    {
       name: 'Material Teal', 
       colors: {
          'primary': { default: [ 0,  150, 136], a100: [167, 255, 237], a200: [100, 255, 218], a400: [ 29, 233, 182], a700: [  0, 191, 165] },
          'accent' : { default: [103,  58, 183], a100: [179, 136, 255], a200: [124,  77, 255], a400: [101,  31, 255], a700: [ 98,   0, 234] },
          'warn'   : { default: [244,  67,  54], a100: [255, 138, 128], a200: [255,  82,  82], a400: [255,  23,  68], a700: [213,   0,   0] }
       }
    }
];

export class ThemeClass {
   name: string;
   colors: ThemeColors;

   constructor(data: Theme) {
      this.name = data.name;
      this.colors = data.colors;
   }
}

new ThemeClass(themes[0]);

(code in playground)