Лучший способ решить ошибку typescript — свойство не существует для типа

#javascript #jquery #angularjs #d3.js #typescript

#javascript #jquery #angularjs #d3.js #typescript

Вопрос:

У меня есть несколько разных ситуаций, когда я пытаюсь определить самодельное свойство для массива или объекта в typescript, но обычно получаю ошибку:

«Свойство x не существует для типа Object (или типа Array)»

Например, я использую typescript в Angular и имею определенную область действия на основе файла определения типа Angular:

 scope:ng.IScope
  

Но затем, когда я пытаюсь создать новое свойство в области видимости, выполнив:

 scope.anotherProperty = "string";
  

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

 scope["anotherProperty"] = "string";
  

или

 (<any>scope).anotherProperty = "string;
  

Другой пример — когда у меня есть что-то подобное в моем графике d3:

 function panZoomNode (node:any) {
            for (var i = 0; i < renderedNodes.length; i  ) {
                if (node.id === renderedNodes[i].id) {

                    }
                }
        }
  

В идеале я хотел бы изменить этот параметр (node: any) на что-то вроде:

 (node:Object)
  

Но когда я это делаю, я получаю сообщение об ошибке «идентификатор свойства не существует для типа Object». Я знаю, что могу исправить это с помощью решений, о которых я упоминал выше, но это кажется мне небрежным. Есть ли лучший способ или лучший способ typescript заставить их работать правильно как для массивов, так и для объектов?

Спасибо

Комментарии:

1. Можете ли вы наследовать от ng. Я думаю, добавить еще одно свойство в определение и использовать его? Последняя проблема вызвана тем, что объект не имеет свойства id . Либо вы оставляете его свободно набираемым с помощью any, либо создаете класс / интерфейс.

2. Да, я должен иметь возможность наследовать от этого, каков наилучший способ добавить определение тогда? Позволит ли это мне сделать что-то вроде «scope.anotherProperty = string». Кроме того, если бы я собирался добавить интерфейс, я бы хотел просто установить все свойства, которые потенциально может иметь объект узла, или если я просто использую id, мне лучше просто добавить id? а затем вызовите это в определении параметра. Спасибо

3. Я добавил ответ ниже. Вместо наследования от ng. Возможно, вы можете просто расширить его.

Ответ №1:

Вы можете добавить дополнительное свойство к ng.IScope интерфейсу, добавив в свой код следующее:

 interface ng.IScope {
    anotherProperty?:string;
}
  

Это позволит вам вызвать

 scope.anotherProperty = "string";
  

Не видя остальной части вашего кода и не зная, что node на самом деле представляет, я могу только сказать, что для того, чтобы компилятор был доволен, вам нужно просто включить элементы, на которые вы ссылаетесь, в свой TS-код. Если вы все делали правильно, создайте класс, содержащий все члены. Если оно является производным от существующего класса или реализует существующий интерфейс, тогда вы должны наследовать от тех, которые указаны в вашем определении класса.

Редактировать: если вы еще этого не сделали, вам следует поискать определения D3 в репозитории DefinitelyTyped на GitHub. Предполагая node , что это тип D3, вы можете использовать это для решения своей проблемы и избежать написания собственного класса.

Комментарии:

1. Да, в итоге я просто расширил ng. Я проверяю и добавляю дополнительные свойства, к которым мне нужно было получить доступ. Это работает нормально. Моему редактору не понравилось просто использовать интерфейс, как вы описали в своем ответе. Для узла я просмотрел определения типа D3, но в моем случае там ничего не работает для узла, поскольку я также использую dagre-d3 с определенными свойствами. Я только что создал интерфейс и добавил нужные мне свойства, которые сработали для меня. Спасибо