Как выбрать строковый член объекта - PullRequest
0 голосов
/ 11 июля 2020

У меня есть следующее определение

interface IAutoCompleteInputProps<T> {
    textMember: keyof T;
    imageMember: keyof T;
    data: T[];
}

Но я также хочу убедиться, что значение T[textMember] тоже должно быть string. Как я могу этого добиться?

=== Обновление: После того, как я реализовал ответ @R Pasha, когда я пытаюсь получить доступ к textMember с помощью a.data[a.textMember] (я ожидаю, что он быть строкой), но IDE говорит, что

(property) value: T[{ [K in keyof T]: T[K] extends string ? K : never; }[keyof T]]
Type 'T[{ [K in keyof T]: T[K] extends string ? K : never; }[keyof T]]' is not assignable to type 'string'.
  Type 'T[T[keyof T] extends string ? keyof T : never]' is not assignable to type 'string'.
    Type 'T[keyof T]' is not assignable to type 'string'.
      Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'string'.
        Type 'T[string]' is not assignable to type 'string'.ts(2322)

я могу преобразовать его в строку, но просто хочу знать, почему? Спасибо

PS код, в котором я получил ошибку

function Application<T>(props: IAutoCompleteInputProps<T>) {
  const x = props.data[0][props.textMember]; // x here is not string
}

Вот Ссылка на игровую площадку

Ответы [ 2 ]

1 голос
/ 11 июля 2020

можно использовать Условные типы

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

interface IAutoCompleteInputProps<T>{
    textMember: keyof StringProperties<T>;
    imageMember: keyof T;
    data: T[];
}

interface Type1 {
  field1: number; // <- is number
  field2: string;
}

let x : IAutoCompleteInputProps<Type1> = {
  textMember : 'field1', // <- field1 must be string
  imageMember: 'field2',
  data: []

}
0 голосов
/ 11 июля 2020

Выберите свойства строкового значения с помощью этого помощника:

type PropertyOfValue<T, V> = {
  [K in keyof T]-?: T[K] extends V
    ? K
    : never
}[keyof T];

Использование:

interface Type1 {
  field1: number; 
  field2: string;
}

const props: IAutoCompleteInputProps<Type1> = {
  data: [
    { field1: 42, field2: 'foo' }
  ],
  imageMember: 'field1',
  textMember: 'field2'
}

props.textMember; // "field2"
props.data[0][props.textMember]; // string

TypeScript Playground

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