TypeScript: почему наличие здесь `keyof` может решить эту проблему - PullRequest
1 голос
/ 03 августа 2020

Я пытался написать функцию для возврата массива значений в объекте

  a: 1,
  b: 2,
  c: 3,
}

const r = Object.keys(obj).map((key) => {
  let val = obj[key]
  return val
})

Здесь компилятор TS показал ошибку, говоря, что

Элемент неявно имеет 'любой' тип, потому что выражение типа 'строка' не может использоваться для индексации типа '{a: number; б: число; c: номер; } '. Индексная подпись с параметром типа 'строка' не найдена для типа '{a: number; б: число; c: номер; } '. ts (7053)

Я не могу понять, что это означает, но я думал, что это как-то связано с тем, что key является строкой. поэтому я попробовал это вместо

let obj = {
  a: 1,
  b: 2,
  c: 3,
}

const r = Object.keys(obj).map((key) => {
  let val = obj[key as keyof typeof obj] // the error now is gone
  return val
})

console.log('r', r)

Теперь ошибки нет. Я не совсем уверен, почему. все, что я знаю, это то, что keyof даст тип разрешенных имен свойств на obj, но я не знаю, для какой цели typeof служит здесь

1 Ответ

1 голос
/ 03 августа 2020

Typescript определяет тип вашего объекта obj как:

type Obj = {
  a: number
  b: number
  c: number
}

Это также может быть выражено как:

type Obj = {[key in 'a' | 'b' | 'c']: number};

'a' | 'b' | 'c' является подтипом string. Однако, когда вы используете Object.keys(obj), машинописный текст предполагает, что возвращаемый тип здесь будет string[], а не ('a' | 'b' | 'c')[]. Вот почему он жалуется на No index signature with a parameter of type 'string' was found on type '{ a: number; b: number; c: number; }' - потому что вы не можете использовать какие-либо string для поиска значений в obj, вместо этого вам нужно использовать определенные c ключи.

Оператор keyof принимает тип в качестве входных данных и возвращает предоставленные ключи. Причина, по которой вам нужно typeof, заключается в том, чтобы вывести тип объекта (в противном случае вы бы сделали keyof obj, который машинописный текст не понимает, поскольку obj не является типом)

keyof typeof obj - это выводится как "a" | "b" | "c"

Keyof - https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof -and-lookup-types

Typeof - https://mariusschulz.com/blog/type-queries-and-typeof-in-typescript#typescripts -type-questions

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...