Условные сопоставленные типы Typescript теряют информацию о возвращаемых типах - PullRequest
1 голос
/ 10 июня 2019

Я пытаюсь обернуть голову вокруг условных картографических типов. Если у меня есть тип, определенный как:

type StringyProps<T> = { [K in keyof T]: T[K] extends string ? K : never }[keyof T];

Что делает конструкция [keyof T] в конце? Как найти документацию о том, что вы можете сделать с этим?

Также я написал функцию:

function getString<T>(thing: T, prop: StringyProps<T>): string {
  return thing[prop] as string;
}

Если у меня есть следующий интерфейс:

interface Something {
  name: string,
  id: string,
  age: number,
  weight: number
}

Я получаю следующие ошибки во время компиляции:

console.log(getString(pippy, "name")); // ok
console.log(getString(pippy, "age")); // age is not assignable to parameter of type "name" | "id"

Это довольно круто, но моя функция не скомпилируется, потому что может быть ошибкой назначать значение StringyProp в строку. Если я изменяю возврат на return thing[prop] as unknown as string, он возвращает правильное значение.

Как я могу построить это так, чтобы мне не приходилось утверждать неизвестную и повторно утверждать строку?

1 Ответ

1 голос
/ 10 июня 2019

Typescript не может следовать тому факту, что StringyProps<T> представляет только string ключи prfoperty.Лучшее решение - использовать утверждение типа:

function getString<T>(thing: T, prop: StringyProps<T>): string {
  return thing[prop] as unknown as string;
}

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

function getString<K extends PropertyKey>(thing: Record<K, string>, prop: K): string {
  return thing[prop]; // ok no assertion
}

console.log(getString(pippy, "name")); // ok
console.log(getString(pippy, "age")); //err
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...