I'm trying to add some aliases to an array of numbers but typescript wont accept it, here is the code:
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]
compiler error:
Type 'number[]' is not assignable to type 'number[] & FontSizeAliases'.
Type 'number[]' is missing the following properties from type 'FontSizeAliases': micro, small, default, large
CodePudding user response:
The problem is that your array doesn't have micro
etc. when you assign it to the fontSizes
constant, but that constant's type requires it.
Object.assign
is often used to build up things like that (but keep reading, I build up to a third option which I think is probably best):
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],
});
Another option is to build them up in a 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;
In both of those, though, you have the issue that you could miss out one of the sizes (small
, for instance). To fix that, you can create the sizes separately:
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);
CodePudding user response:
I would suggest to slightly modify your types, like this:
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]
I've made micro optional, this will give you intellisense and make sure you will not forget to check undefined