Typescript: приведение типа при вычислении свойства

#typescript

Вопрос:

Версия машинописного текста: 4.2.3

Я хочу сделать значения union ключом типа объектного литерала, как показано ниже:

 type Values = "888" | "123"
type Something = {
  [key in Values] : number
}
 

Так что я могу получить доступ к значению объекта, например something["888"] .

Но результат-это не то, чего я хочу:

 // What I want:
// property are **string** type
type Something = {
  "888": string;
  "123": string;
}

// But the real result is:
// property became **number** type. 
type Something = {
  888: string;
  123: string;
}
 

Я не могу понять, почему это происходит ?
И есть ли какой-нибудь способ решить эту проблему?

Ответ №1:

Свойства объекта всегда являются строками. Все работает так, как задумано.

Давайте добавим что-то, что нельзя было бы принудить к числу:

 type Values = "888" | "123" | "asdf"
type Something = {
  [key in Values] : number
}
 

Теперь, если вы наведете курсор мыши Something , вы должны увидеть:

 type Something = {
    888: number;
    123: number;
    asdf: number;
}
 

Во всплывающем окне типа отображаются свойства без кавычек, потому что это синтаксис, который будет использоваться литералом объекта.

Например:

 const foo: Something = {
  888: 123,
  123: 456,
  asdf: 789,
}
const foo888 = foo["888"]
 

Здесь объект foo имеет свойства имен "888" , "123" и "asdf" .


В обычных объектах javascript имена их свойств всегда хранятся в виде строк. Но принуждение к цифрам допускается. Typescript позволяет вам делать то же самое:

 // both work fine
const foo888string = foo["888"]
const foo888number = foo[888]
 

Комментарии:

1. Таким образом, свойства объекта всегда являются строковыми. Всплывающее сообщение, подсказка IDE, — это просто синтаксис, который делает этот объект буквальным. Это не значит, что это настоящий тип.

2. Это реальный тип, потому что ключи объектов всегда являются строками. Object.keys({ 888: 123 }) ВОЗВРАТ ["888"]

3. Спасибо. Мне кажется, я кое-что понял из вашего ответа.