Как затипизировать массив, который является списком ключей объекта?

Ссылка скопирована
1 ответ

Подскажите, как затипизировать массив ENTITIY_LIST, зная все его значения Entity_Listили по факту из полученных значений через ENTITIES

interface Entity {     name: string     url: string }  type Entity_List = 'cities' | 'companies' | 'countries'  const ENTITIES: Record<Entity_List, Entity> = {     cities,     companies,     countries, }  const ENTITIY_LIST = Object.keys(ENTITIES)

interface Entity { name: string url: string } type Entity_List = 'cities' | 'companies' | 'countries' const ENTITIES: Record<Entity_List, Entity> = { cities, companies, countries, } const ENTITIY_LIST = Object.keys(ENTITIES)

Суть проблемы в конструкции

{ENTITIY_LIST.map(item => {     const entity = ENTITIES[item] }

{ENTITIY_LIST.map(item => { const entity = ENTITIES[item] }

Где возможно есть элегантное и надежное решение без as
ENTITIES[item as keyof typeof ENTITIES]

Дополнительно:

const toKeys = Object.keys as <T extends object>(obj: T) => (keyof T)[];

const toKeys = Object.keys as <T extends object>(obj: T) => (keyof T)[];

  • WbICHA, казалось без as есть вариант
    Подскажи пожалуйста, изначально проблема выходит отсюда
    {ENTITIY_LIST.map(item => {     const entity = ENTITIES[item] }

    {ENTITIY_LIST.map(item => { const entity = ENTITIES[item] }

    Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Record<Entity_List, Entity>'.   No index signature with a parameter of type 'string' was found on type 'Record<Entity_List, Entity>'.

    Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Record<Entity_List, Entity>'. No index signature with a parameter of type 'string' was found on type 'Record<Entity_List, Entity>'.

    И мне казалось, что наверно есть простой способ затипизировать массив и в итоге эта ошибка уйдет.
    Потому что решение ENTITIES[item as keyof typeof ENTITIES] через as мне показалось не столь надежным, которым можно было бы сделать через типизацию массива путем значений

  • MishaXXL,

    казалось без as есть вариант

    Всё же есть большая разница между типизацией конкретной утилити функции и замены типа прямо в коде. Моё решение выше полностью безопасно, а предложенное тобой, в целом, тоже безопасно, только куда как больше мест для ошибки, ведь ключ может использоваться в нескольких местах и, главное, аналогично тебе придётся делать во всём приложении.
    Короче, использование самого as не есть плохо, в некоторых случаях без этого никак.

    Можешь ещё так делать:

    const ENTITIY_LIST = Object.keys(ENTITIES) as (keyof typeof ENTITIES)[]

    const ENTITIY_LIST = Object.keys(ENTITIES) as (keyof typeof ENTITIES)[]

  • WbICHA, спасибо, это решение нравится больше )
    Добавь пожалуйста в ответы, чтобы закрыл вопрос
  • Универсальное решение:

    const toKeys = Object.keys as <T extends object>(obj: T) => (keyof T)[];  const ENTITIY_LIST = toKeys(ENTITIES)

    const toKeys = Object.keys as <T extends object>(obj: T) => (keyof T)[]; const ENTITIY_LIST = toKeys(ENTITIES)

    Решение на раз:

    const ENTITIY_LIST = Object.keys(ENTITIES) as (keyof typeof ENTITIES)[]

    const ENTITIY_LIST = Object.keys(ENTITIES) as (keyof typeof ENTITIES)[]

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Никита Орлов Ответ

    Для того чтобы затипизировать массив, который является списком ключей объекта, можно воспользоваться PHPDoc блоком над переменной, указывая тип данных, которые должны содержаться в массиве.

    Пример:

    /**
     * @var string[] $keysList
     */
    $keysList = ['key1', 'key2', 'key3'];

    /** * @var string[] $keysList */ $keysList = ['key1', 'key2', 'key3'];

    В данном примере мы определили переменную $keysList как массив строк (string[]), который содержит список ключей объекта. Теперь PHPStorm или другой IDE сможет подсказывать доступные методы и свойства для каждого элемента массива.

    Если же вы используете PHP 7.4 или более позднюю версию, то можно воспользоваться встроенными типами данных для массивов. Например, для списка ключей объекта можно использовать тип данных array-key[]:

    $keysList = ['key1', 'key2', 'key3'];

    $keysList = ['key1', 'key2', 'key3'];

    Таким образом, вы можете явно указать тип данных, которые могут содержаться в массиве, что поможет избежать ошибок и улучшит читаемость кода.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно