#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 Извините, не понял, что вам это тоже нужно. В любом случае вам удалось исправить это самостоятельно