Использование внешней JS-библиотеки (диаграммы базовых примитивов) в Typescript

#javascript #typescript

#javascript #typescript

Вопрос:

Я делаю первые шаги по переносу довольно большого проекта с javascript на typescript. Будучи разработчиком Java, который начал разработку javascript всего около 2 лет назад, мой набор инструментов все еще находится в зачаточном состоянии.

Я пытаюсь перенести небольшой JS-файл в TS в качестве доказательства концепции. JS-код настраивает диаграмму базовых примитивов.

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

 export {}
declare global {
  export interface Window {
    MyGlobalVar: any;
  }

  export ChartItemConfig{
    //properties
  }

  //I thought this and the following declarations would solve the problem. They dont :(
  export interface primitives {
    orgdiagram: Orgdiagram;
  }

  export interface Orgdiagram {
    Config: Config;
  }

  export interface Config {
    //properties
  }
}

window.MyGlobalVar.myGlobalFunction = function (id: string, items: Array<ChartItemConfig>) {
    //... more code
    // @ts-ignore
    let options: Config = new primitives.orgdiagram.Config();
    //... more code
 }
  

Я хочу избавиться от @ts-ignore инструкции. Но что бы я ни пытался, мой код не будет транспилироваться. Я получаю сообщение об ошибке TS2693: 'primitives' only refers to a type, but is being used as a value here.

Я уверен, что это проблема для начинающих, но я не могу найти решение в www.

Редактировать:

Кажется, я недостаточно четко сформулировал свою проблему: new primitives.orgdiagram.Config(); допустим ли JS-код во время выполнения. Как я могу объявить символ таким образом, чтобы TS понял, что это вызов конструктора?

Редактировать:

Текущая версия:

 export {}
declare global {
  export interface Window {
    MyGlobalVar: any;
  }

  export const primitives:Primitives;

  export class Primitives {
    orgdiagram: Orgdiagram;
  }

  export class Orgdiagram {
    Config: () => Config;
  }

  export class Config { }
  
  //... more
}

window.MyGlobalVar.myGlobalFunction  = function (id: string, items: Array<ChartItemConfig>) {
  //The following line fails with: TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type
  let options: Config = new primitives.orgdiagram.Config();
  //... more
}
  

Редактировать:

Я, наконец, заставил это работать. fettblog.eu познакомил меня с шаблоном интерфейса конструктора, который решил мою проблему 🙂

Теперь мое рабочее объявление

 export {}
declare global {
      
  const primitives:Primitives;

  class Primitives {
    orgdiagram: Orgdiagram;
  }

  class Orgdiagram {
    Config: ConfigConstructor;
  }

  interface ConfigConstructor{
    new (): Config;
  }

  class Config {
    //....
  

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

1. Я думаю, вы неправильно поняли, для чего предназначены интерфейсы, они равны типам / классам, но вместо их создания вы можете создать объект, который должен соответствовать свойствам интерфейса, также известного как. export interface Person { name: string } const myPerson: Person = { name 'Mike' }

2. Сам интерфейс не существует во время выполнения, он существует только для ts-компилятора.

Ответ №1:

Что вам нужно сделать, так это объявить const :

 declare global {
    export const primitives: Primitives

    export interface Primitives {
        orgdiagram: Orgdiagram;
    }
}
  

Таким образом, вы сообщаете Typescript: «поверь мне, где-то еще в глобальной области видимости объявлена константа, которая вызывается primitives и тип которой Primitives «. И это генерирует правильный код.

Что касается конструктора, вам нужно указать, что функция является конструктором, чтобы иметь возможность использовать ее с new :

 export class Orgdiagram {
    Config: { new(): Config };
}
  

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

1.О, спасибо, огромный шаг в правильном направлении. Но все еще существует проблема, TS не знает, как обращаться с конструктором. Текущий код: export const primitives:Primitives; export class Primitives { orgdiagram: Orgdiagram; } export class Orgdiagram { Config: () => Config;} export class Config {} Текущая ошибка: TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. извините за беспорядок с форматированием

2. @samjaf Извините, не понял, что вам это тоже нужно. В любом случае вам удалось исправить это самостоятельно