I have an array of string literals that I'd like to use as property names for a class.
const propNames = ["a", "b", "c"] as const;
I would like to create a class like
class Test {
[name in typeof propNames[number]]: any;
}
But this gives the errors (in WebStorm inspection):
TS1166: A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type.
TS2464: A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
TS2361: The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.
TS2693: 'number' only refers to a type, but is being used as a value here.
I can instead define a type with those properties like
type Test = {
[name in typeof propNames[number]]: any;
}
But I don't know a way of turning this into a class with those properties.
I have an extra question that I don't think is possible currently, but could I create those property names by concatenating another string literal to them?
type Test = {
[name + 'Prop' in typeof propNames[number]]: any;
}
I got around this (including the extra question) by defining intermediate types and using them like namespaces:
const propNames = ["a", "b", "c"] as const;
// using DOM types for demonstration
type Canvases {
[name in typeof propNames[number]]?: HTMLCanvasElement;
}
type Contexts {
[name in typeof propNames[number]]?: CanvasRenderingContext2D;
}
// define class
class Test {
canvases: Canvases = {};
ctxs: Contexts = {};
}
// now access on instances
const t = new Test();
t.canvases.a; // HTMLCanvasElement
t.ctxs.b; // CanvasRenderingContext2D