如何在 typescript 中为数字数组添加别名

ffdz8vbo  于 2023-05-08  发布在  TypeScript
关注(0)|答案(3)|浏览(120)

我试图添加一些别名到一个数组的数字,但 typescript 不会接受它,这里是代码:

interface FontSizeAliases {
  micro: number
  small: number
  default: number
  large: number
}

const fontSizes: number[] & FontSizeAliases = [12, 14, 16, 18, 22, 30, 40]
fontSizes.micro = fontSizes[0]
fontSizes.small = fontSizes[1]
fontSizes.default = fontSizes[2]
fontSizes.large = fontSizes[3]

编译器错误:

Type 'number[]' is not assignable to type 'number[] & FontSizeAliases'.
  Type 'number[]' is missing the following properties from type 'FontSizeAliases': micro, small, default, large
2guxujil

2guxujil1#

问题是你的数组没有micro等等。当你把它赋值给fontSizes常量时,但是这个常量的类型需要它。
Object.assign经常被用来构建这样的东西(但请继续阅读,我认为第三个选项可能是最好的):

interface FontSizeAliases {
    micro: number;
    small: number;
    default: number;
    large: number;
}

const rawSizes = [12, 14, 16, 18, 22, 30, 40];
const fontSizes: number[] & FontSizeAliases = Object.assign(rawSizes, {
    micro: rawSizes[0],
    small: rawSizes[1],
    default: rawSizes[2],
    large: rawSizes[3],
});

Playground链接
另一种选择是在Partial<FontSizeAliases>中构建它们:

interface FontSizeAliases {
    micro: number;
    small: number;
    default: number;
    large: number;
}

const rawSizes: number[] & Partial<FontSizeAliases> = [12, 14, 16, 18, 22, 30, 40];
rawSizes.micro = rawSizes[0];
rawSizes.small = rawSizes[1];
rawSizes.default = rawSizes[2];
rawSizes.large = rawSizes[3];
const fontSizes = rawSizes as number[] & FontSizeAliases;

Playground链接
但是,在这两种情况下,您都有可能遗漏其中一个大小(例如small)的问题。要修复 that,你可以用全类型检查单独创建大小,然后将它们组合起来:

interface FontSizeAliases {
    micro: number;
    small: number;
    default: number;
    large: number;
}

const rawSizes = [12, 14, 16, 18, 22, 30, 40];
const sizeNames: FontSizeAliases = {
    micro: rawSizes[0],
    small: rawSizes[1],
    default: rawSizes[2],
    large: rawSizes[3],
};
const fontSizes = Object.assign([], rawSizes, sizeNames);

Playground链接

68de4m5k

68de4m5k2#

我建议稍微修改一下你的类型,像这样:

interface FontSizeAliases {
    micro?: number
    small?: number
    default?: number
    large?: number
}

const fontSizes: number[] & FontSizeAliases = [12, 14, 16, 18, 22, 30, 40]

fontSizes.micro = fontSizes[0]
fontSizes.small = fontSizes[1]
fontSizes.default = fontSizes[2]
fontSizes.large = fontSizes[3]

我已经使微可选,这将给予你intellisense,并确保你不会忘记检查未定义
链接到操场

qv7cva1a

qv7cva1a3#

我想通过建立一个效用函数来减少样板文件。它确实有一个@ts-ignore,但您可以重复使用它而不会出错。
此版本允许您手动指定每个索引:

const keyedArray = <T, U extends string>(
  values: T[],
  names: { [k in U]: number }
): T[] & { [k in U]: T } => {
  // @ts-ignore
  return Object.assign(
    [...values],
    Object.entries<number>(names).reduce(
      (acc, [name, index]) => ({
        ...acc,
        [name]: values[index],
      }),
      {}
    )
  );
};

const fontSizes = keyedArray([0, 2, 16], { sm: 0, lg: 1, xl: 2 });
/*
const fontSizes: number[] & {
    sm: number;
    lg: number;
    xl: number;
}
*/

相关问题