Создание свойств вычисляемого класса из массива

У меня есть массив строковых литералов, которые я хотел бы использовать в качестве имен свойств для класса.

const propNames = ["a", "b", "c"] as const;

Я хотел бы создать класс вроде

class Test {
    [name in typeof propNames[number]]: any;
}

Но это дает ошибки (при проверке WebStorm):

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.

Вместо этого я могу определить тип с такими свойствами, как

type Test = {
    [name in typeof propNames[number]]: any;
}

Но я не знаю, как превратить это в класс с такими свойствами.

У меня есть дополнительный вопрос, который, как мне кажется, в настоящее время невозможен, но могу ли я создать эти имена свойств, объединив их с другим строковым литералом?

type Test = {
    [name + 'Prop' in typeof propNames[number]]: any;
}

person LemonPi    schedule 18.05.2020    source источник


Ответы (2)


Почему бы не определить тип, а затем использовать его через:

type Test = {
    [key: TEST]: any;
} 

где ТЕСТ - это тип. Я никогда не рисковал делать это, но знаю, что это работает для примитивных типов.

Надеюсь, он доставит вас туда, куда вам нужно!

person iamaword    schedule 18.05.2020
comment
Я бы хотел определить свойства внутри класса, а не типа (что я уже могу сделать). Кроме того, это похоже на синтаксическую ошибку? TS1023: An index signature parameter type must be either 'string' or 'number'. - person LemonPi; 30.05.2020

Я обошел это (включая дополнительный вопрос), определив промежуточные типы и используя их как пространства имен:

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
person LemonPi    schedule 30.05.2020