Как набрать глубокую деструктуризацию объекта в Typescript? - PullRequest
0 голосов
/ 21 декабря 2018

Я пытаюсь ввести глубокую деструктуризацию объектов в Typescript, и я искал целую группу, но не нашел ничего, что вполне отвечало бы на мой вопрос, поэтому я подумал, что задам его.

У меня есть кое-что как это в моем классе:

public Example(
  key1: string,
  key2: string,
  val: string,
  callback: (list: string[]) => void
): void
{
  chrome.storage.sync.get(
    ({
      [key1]: list1,
      [key2]: list2
    }) => {
      list1.includes(val)
        ? callback(list1.filter(i => i !== val))
        : callback(list2)
    }
  );
}

Я не нашел способ набрать list1 и list2 (как string[]), и они установлены как anyчто бесполезно для меня при попытке использовать функции массива.Я нашел примеры того, как печатать, если key известен ({ key }: { key: string[] }), но не для моей ситуации.Я также не могу создать Тип, поскольку LHS не является статичным.

Мой пример несколько изменен, но содержит все необходимое, чтобы ответить на мой вопрос.

В случае необходимости, chrome.d.ts У меня есть состояния:

/**
 * Gets one or more items from storage.
 * @param callback Callback with storage items, or on failure (in which case runtime.lastError will be set).
 * Parameter items: Object with items in their key-value mappings.
 */
get(callback: (items: { [key: string]: any }) => void): void;

Я уверен, что это, вероятно, действительно просто, и я просто ничего не нашел;При этом, этот вопрос может облегчить поиск других людей в будущем, поэтому он будет беспроигрышным, если будет решен.

Я ценю всех и любую помощь.


РЕДАКТИРОВАТЬ: Я думаю, я также ищу случай, когда это не просто string[], который возвращается.Что если у вас есть целая куча данных, которые были разных типов?

Ответы [ 2 ]

0 голосов
/ 22 декабря 2018

Используйте объявление слияния для исправления сторонних типов:

chrome.d.ts

import {} from 'chrome';

declare namespace chrome.storage {
  export interface StorageArea {
    get(callback: (items: { [key: string]: string[] }) => void): void;
  }
}

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

Что лучше в этом?Если вас не устраивает string[], вы можете увеличить его другим способом.Вы также можете сделать get универсальным.

0 голосов
/ 21 декабря 2018

Таким образом, вы получаете тип any, потому что функция get имеет это так.

Следовательно, вы можете сделать это:

type MyGet = (callback: (items: {[key: string]: string[]}) => void) => void

// inside the Example method
(chrome.storage.sync.get as MyGet)(
          ({
            [key1]: list1,
            [key2]: list2
          }) => {
            list1.includes(val)
              ? callback(list1.filter(i => i != val))
              : callback(list2)
          }
        );

Другой и лучший подход в случае, если есть возможность встретиться с другими типами, это использовать охранники типов:

chrome.storage.sync.get(
          ({
            [key1]: list1,
            [key2]: list2
          }) => {

            if(Array.isArray(list1)) {
              list1.includes(val)
                ? callback(list1.filter(i => i != val))
                : callback(list2)
            }
          }
        );

Это нормально с точки зрения безопасности типов, потому что сужение типа any до string[] должно рассматриваться как ОК.

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