Ошибка TS2464 - случай объекта с унаследованными ключами и строчными значениями

В вопросе Создание производного перечисления с ключами исходного в TypeScript я ошибочно предположил, что keyof возвращает именно значения, а не ключи. Мне тогда было сказано, что keyof возвращает именно ключи. Но в этом примере что-то опять не сходится.

type EntryPointsRecognitionSettings__FromFile__RawValid = {
  excludeAllSubdirectories?: boolean;
  excludeSubdirectoriesWithNames?: Array<string> | string;
  excludeSubdirectoriesWithPrefixes?: Array<string> | string;
  excludeFilesWithPrefixes?: Array<string> | string;
};

type PropertiesKeys = { [key in keyof EntryPointsRecognitionSettings__FromFile__RawValid]: string; };

function test(propertiesKeys: PropertiesKeys): void {
    console.log({
        [propertiesKeys.excludeAllSubdirectories]: "ALPHA"
    })
}

В типе PropertiesKeys я вроде как корректно скопировал ключи EntryPointsRecognitionSettings__FromFile__RawValid и указал, что значениями могут быть только строки. Если это так, то propertiesKeys.excludeAllSubdirectories, где propertiesKeys имеет тип PropertiesKeys, должно быть строкой. Тем не менее, судя по ошибке TypeScript, это не так:

A computed property name must be of type 'string', 'number', 'symbol', or 'any'.(2464)

Прошу Вас объяснить, что именно я не понимаю.

? TypeScript playground


Ответы (1 шт):

Автор решения: Grundy

Проблема в ? рядом с именем свойства.

Знак вопроса показывает, что свойство может отсутствовать. Таким образом тип ключей не просто string, а string | undefined.

Из-за этого напрямую такой ключ использовать нельзя, так как для ключей можно использовать только 'string', 'number', 'symbol', или 'any'

Если ты хочешь использовать все ключи, в mapped type нужно указать, что они становятся обязательными

type PropertiesKeys = { [key in keyof EntryPointsRecognitionSettings__FromFile__RawValid]-?: string; };

Теперь ошибки не будет.

Playground Link

→ Ссылка