g1er / Andrew

0 stars 0 forks source link

Вызов других файлов изнутри typescript файлов #19

Open IgorKulishov opened 6 years ago

IgorKulishov commented 6 years ago

Когда у нас имеется несколько исходных ts файлов так что к примеру класс определяется в одном файле, а используется в другом, как в примере ниже, то нам необходимо иметь возможность обратиться из одного в другой файл.

Для этого используется специальный синтаксис внутри typescript - тройная наклонная черта и тэг reference с путем внутри атрибута path:

///<reference path="product-class.ts" /> 

В редакторе VSC имеется встроенный "снипед" который автоматически подставляет всю строку, для его вызова что бы не набирать все в ручную достаточно набрать слово "ref"после чего снизу появится подсказка с вариантами и надо выбрать опцию "triple-slash reference" и кликнуть / выбрать опцию. Далее вписать путь к вызываемому файлу.

Итак для примера создадим два файла в той же рабочей папке: 1) product-class.ts

class Products {
    constructor(private name){
    }
    get productName() {
        return this.name;
    }
    set productName(name) {
        this.name = name;
    }
    public logProductName() {
        console.log("product: ", this.productName);
    }
}

Примечание: мы еще подробно будем говорить о классах, пока же укажу на момент:

 constructor(private name){
    }

это сокращенное:

 private name;
 constructor(name){
     this.name = name;
    }

2) app.ts (в котором мы обращаемся к файлу "product-class.ts"):

/// <reference path="product-class.ts" />
let product = new Products('Car');
product.logProductName();

setTimeout(function() {
    document.body.innerHTML= "product: " + product.productName;
}, 1000);

Так же нам надо поменять конфигурационный файл tsconfig.json - так что после компеляции у нас будет один файл app.js:

{
    "compilerOptions": {
       "target":"es5",
       "outFile": "../js/app.js",
       "sourceMap": true
    }
  }

Примечание: outDir поменялся на outFile с указанием пути и названия файла ../js/app.js

После компеляции должен получиться два файла app.js и его версия для дебагинга app.js.map на выходе. Файл app.js состоит из двух исходных файлов указанных выше, причем если открыть app.js, то можно увидеть внутри откомпелированное и переведенное в формат ES5 (согласно настройкам конф-го файла) содержимое исходных файлов: /// :

var Products = /** @class */ (function () {
    function Products(name) {
        this.name = name;
    }
    Object.defineProperty(Products.prototype, "productName", {
        get: function () {
            return this.name;
        },
        set: function (name) {
            this.name = name;
        },
        enumerable: true,
        configurable: true
    });
    Products.prototype.logProductName = function () {
        console.log("product: ", this.productName);
    };
    return Products;
}());
/// <reference path="product-class.ts" />
var product = new Products('Car');
product.logProductName();
setTimeout(function () {
    document.body.innerHTML = "product: " + product.productName;
}, 1000);
IgorKulishov commented 6 years ago

В той же папке для typescript проделай выше указанное и запусти код. Пожалуйста закомить код в репозитарий. Напиши вопросы.

g1er commented 6 years ago

Сделано. Вопросов каких-то критических тут в общем-то нет. Крома пары синтаксических. Как ты уже указал сам выше, параметр (private name) - это стандарт ES6 или фишка Typescript? Просто сам браузер мне его не распознал, написал Unexpected strict mode reserved word. Это случилось до компиляции, когда я код из TS-файла просто вставил в консоль дебагера.

Да, и слово public мне тоже незнакомо

public logProductName() {
        console.log("product: ", this.productName);
    }

Раньше не встречал такого написания. Интуитивно понятно, что оно может означать, но точного определения я не знаю.

IgorKulishov commented 6 years ago

Объясни пож-та, не понял вопрос : "Это случилось до компиляции, когда я код из TS-файла просто вставил в консоль дебагера.". Браузер не поймет typescript, т.к. язык typescript существует только в среде разработки и уже при компеляции ts компил-ся в js (то что я как раз привел выше - код после компеляции. Или может я не понял вопрос - какой дебагер ты имел ввиду - браузера или редактора?

IgorKulishov commented 6 years ago

После компеляции проверь что index.html загружается правильно в браузере и выполняет скрипты (откомпелировыные в javascript, но в дебагере показывает все таки typescript при помощи файла .map который позволяет показывать в дебагере код в формате ts для отладки). Если все работет, простьба закомитеть код.

IgorKulishov commented 6 years ago

Как ты правильно заметил, public синтаксиса нет в JS6 (это синтакс объектно-ориентированных языков в Java, C, так же он есть и в typescript). Слово public означает что свойство или метод класса может быть доступен / вызван из других классов. В противоложенность public существует private свойство или метод. private свойство или метод доступен к обращению только внутри класса.

Хотя мы будем это подробно проходить я даю объяснение для общего понимания:

// свойства и метод доступный только внутри класса (":any" тип данных мы будем проходить в следующей главе)
private allData : any;
private filterData(data): any { 
  //here we filter and return some data
  // для повтора filter : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
  return data.filter( content => {
     return content['securityType'] === 'open';
  });
};

// свойства и метод доступный дрйгим классам
public filteredData: any;
public printFilteredData(): void {
  this.filteredData = filterData(this.allData);
   console.log(this.filteredData);
};
// теперь public printFilteredData() может быть вызван из другого класса, а filterData только внутри этого класса
// типы данных :any и :void мы будем проходить в следующей и последующей главах соот-но
IgorKulishov commented 6 years ago

Мы будем проходить классы в typescript

g1er commented 6 years ago

Объясни пож-та, не понял вопрос

Я говорил о том, что когда я вставляю код, который написал в файле product-class.ts, в дебагер браузера, мне в ответ консоль выдает вот это: default просто скопировал код и просто вставил его в браузер. Судя по ответу браузера в консоли, он не понял этого (private name). Поэтому я и спросил, может это фишка именно стандарта TS?

Насчет Public и Private, я так понял, что это чисто TS-овский синтаксис, который при компеляции переводится в понятный JS. Насчет Public понятно, вещь понятная и полезная. А вот насчет Private, разве по умолчанию свойства и методы любого класса не принадлежат только этому классу и не недоступны из других классов? Проще говоря, если свойства и методы изначально недоступны для вызова из других классов, зачем лишний раз это указывать?

IgorKulishov commented 6 years ago
  1. как ты правильно заметил JavaScript не имеет таких свойств и методов как private и public, поэтому и ошибка, что бы у нас дебагер перестал ругаться нам надо убрать private и public из кода:

    class Products {
    
    constructor(data){
       name = data;
    }
    get productName() {
        return this.name;
    }
    set productName(name) {
        this.name = name;
    }
    logProductName() {
        console.log("product: ", this.productName);
    }
    }
    let prod = new Products();
    prod.productName = "Friend";
    prod.logProductName();
  2. Насчет public и private в typescript - как раз таки по умолчанию свойство или метод public является по умолчанию, т.е. если не ставить private / public перед методом, то его можно вызвать из другого класса (я покажу это через две главы как только закончим с типами данных). Иногда нам надо скрыть доступ к методам и свойствам что бы избежать случайного вывода на экран не желательной информации на экран (к примеру пароля или токенов). private часто используется на backend когда мы не хотим выбрасывать во frontend конфиденциальную информацию которую может обрабаывать backend.