WedX - журнал о программировании и компьютерных науках

Есть ли способ ограничить общий тип простыми объектами только в машинописном тексте?

Используя машинописный текст, есть ли способ ограничить общий тип, чтобы разрешить только значения объекта типа? Не массив и другие типы.

Например:

function check<O extends object>(ob: O): O {
  return ob
}

check({}) // should be fine
check([]) // should show error, but does not.

Возможный вариант использования в реальном мире:

function extend<A extends object, B extends object>(a: A, b: B): A & B {
  return {
    ...a,
    ...b,
  };
}

// This is fine, return type is { x: number } & { y: string }
extend({x: 5}, {y: "str"})

// This should not be allowed
// Return type is number[] & string[]
// Accessing a property yields impossible types like number & string
extend([1,2,3], ["s", "i", "d"])

// More examples for variants which I don't want to allow
extend({}, function() {})
extend({}, new Map())
05.04.2019

  • Это на самом деле весело, так как каждый массив тоже является объектом. 05.04.2019

Ответы:


1

Вы можете использовать условный тип для добавления к параметру параметра, если O расширяет any[]. То, что вы добавляете, может гарантировать, что вызов будет ошибкой. Обычно я добавляю типы строковых литералов и думаю о них как о пользовательском сообщении об ошибке:

function check<O extends object>(ob: O & (O extends any[] ? "NO Arrays !" : {})): O
function check<O extends object>(ob: O): O {
  return ob
}

check({}) // should be fine
check([]) // error
05.04.2019
  • Отлично, я думал о чем-то подобном, но я не придумал этот союз, который делает все это гораздо более элегантным. 05.04.2019
  • Хорошо, есть ли причина, по которой вам нужна перегрузка? Кажется, он отлично работает только с первой подписью без второй перегрузки. 05.04.2019
  • Это будет работать только с массивами. Я стараюсь избегать любого типа, который не является простым объектом. 05.04.2019
  • @bugs пересечение с условной будет иметь тенденцию мешать другим вещам, не для этого простого примера, но я подумал, что лучше всего сохранить условную подпись отдельно, вы можете сделать это и только с одним типом. 05.04.2019
  • @sidoshi, что ты имеешь в виду под простым объектом? object не позволит примитивы, такие как число или строка. Если вам не нужны экземпляры класса, я должен подумать об этом. 05.04.2019
  • @TitianCernicova-Dragomir Под простыми объектами я подразумеваю объекты, созданные с использованием литерала объекта: {} или с использованием new Object(){}. В идеале он не должен допускать различных других вещей, которые будут иметь значение typeof как object, таких как функции, массивы и экземпляры классов. Извините, я не был достаточно ясен, когда задавал вопрос. 05.04.2019
  • @sidoshi Боюсь, это невозможно ... мы можем сделать некоторую эвристику, например, разрешить только объекты без функций, что может быть достойным прокси для отсутствия классов, поскольку классы обычно имеют методы. Но он несовершенен, так как он одновременно разрешает некоторые классы (классы без каких-либо методов) и также запрещает некоторые литералы объектов (те, которые содержат функции), но это зависит от вашего варианта использования, является ли это приемлемым компромиссом. 05.04.2019
  • @TitianCernicova-Dragomir Интересно, есть ли способ разрешить только объекты, у которых есть __proto__ = {}? Хотя {} имеет свойство __proto__, установленное на {}, я не могу использовать это свойство в качестве ограничения типа для универсального. 05.04.2019
  • Машинописный текст @sidoshi не поддерживает __proto__, поэтому у него нет связанного типа (на самом деле его использование является ошибкой). Я тоже думал о constructor, но это набирается как Function 05.04.2019

  • 2

    В более новых версиях Typescript вы можете использовать object & Exclude<T, any[]> для представления объекта, который не может быть массивом.

    12.11.2020
    Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]