├── pages ├── .gitignore ├── Typings for NPM Packages.md ├── Writing Declaration Files.md ├── tutorials │ ├── Angular 2.md │ ├── Knockout.md │ ├── ASP.NET 4.md │ ├── React & Webpack.md │ └── ASP.NET Core.md ├── declaration files │ ├── templates │ │ ├── global-plugin.d.ts │ │ ├── module-plugin.d.ts │ │ ├── global-modifying-module.d.ts │ │ ├── module.d.ts │ │ ├── module-class.d.ts │ │ ├── global.d.ts │ │ └── module-function.d.ts │ ├── Consumption.md │ ├── Introduction.md │ ├── Publishing.md │ ├── By Example.md │ ├── Do's and Don'ts.md │ └── Deep Dive.md ├── Iterators and Generators.md ├── Nightly Builds.md ├── Symbols.md ├── Type Inference.md ├── Enums.md ├── Mixins.md ├── Triple-Slash Directives.md ├── tsconfig.json.md ├── Integrating with Build Tools.md ├── Namespaces and Modules.md ├── Basic Types.md ├── Compiler Options in MSBuild.md ├── JSX.md ├── Namespaces.md ├── Declaration Merging.md └── Type Compatibility.md ├── .gitignore ├── .travis.yml ├── .gitattributes ├── assets └── images │ └── tutorials │ └── aspnet │ ├── new-item.png │ ├── new-folder.png │ ├── open-index.png │ ├── paused-demo.png │ ├── src-folder.png │ ├── new-tsconfig.png │ ├── running-demo.png │ ├── new-asp-project.png │ ├── scripts-folder.png │ ├── new-asp-project-empty.png │ ├── task-runner-explorer.png │ ├── new-asp-project-template.png │ ├── packageinstaller-angular2.png │ ├── packageinstaller-es6-shim.png │ ├── packageinstaller-systemjs.png │ └── packageinstaller-typings.png ├── README.md ├── package.json ├── pull_request_template.md ├── CONTRIBUTING.md ├── README.md~ ├── lint.js └── LICENSE /pages/.gitignore: -------------------------------------------------------------------------------- 1 | *.md~ 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "node" -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Normalize line endings for all text files. 2 | * text=auto 3 | -------------------------------------------------------------------------------- /pages/Typings for NPM Packages.md: -------------------------------------------------------------------------------- 1 | > ## This page has been moved to [Publishing](./declaration files/Publishing.md) 2 | -------------------------------------------------------------------------------- /pages/Writing Declaration Files.md: -------------------------------------------------------------------------------- 1 | > ## This page has been moved to [Publishing](./declaration files/Introduction.md) 2 | -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/new-item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/new-item.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/new-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/new-folder.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/open-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/open-index.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/paused-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/paused-demo.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/src-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/src-folder.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/new-tsconfig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/new-tsconfig.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/running-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/running-demo.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/new-asp-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/new-asp-project.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/scripts-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/scripts-folder.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/new-asp-project-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/new-asp-project-empty.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/task-runner-explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/task-runner-explorer.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/new-asp-project-template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/new-asp-project-template.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/packageinstaller-angular2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/packageinstaller-angular2.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/packageinstaller-es6-shim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/packageinstaller-es6-shim.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/packageinstaller-systemjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/packageinstaller-systemjs.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/packageinstaller-typings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddaytoday/TypeScript-Handbook-RU/HEAD/assets/images/tutorials/aspnet/packageinstaller-typings.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Руководство TypeScript на русском 2 | 3 | [![Build Status](https://travis-ci.org/Microsoft/TypeScript-Handbook.svg)](https://travis-ci.org/Microsoft/TypeScript-Handbook) 4 | 5 | Этот репозиторий является переводом [TypeScript Handbook](https://github.com/Microsoft/TypeScript-Handbook). 6 | 7 | Последнюю версию вы всегда сможете найти на сайте [документации Typescript на русском](http://typescript-lang.ru/docs/). 8 | 9 | Если вы заметите расхождение со оригинальной спецификацией, буду благодарен за Pull request. 10 | 11 | 12 | [Официальная спецификация языка](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md). 13 | -------------------------------------------------------------------------------- /pages/tutorials/Angular 2.md: -------------------------------------------------------------------------------- 1 | Angular 2 — грядущий фреймворк, написанный на TypeScript. 2 | Использовать TypeScript с Angular очень просто, поскольку TypeScript прекрасно для этого подходит. 3 | Кроме того, TypeScript занимает почетное место в документации Angular. 4 | 5 | По этой причине [официальный сайт Angular 2](https://angular.io) всегда является наиболее актуальным справочником по использованию Angular с TypeScript. 6 | Прочтите [руководство по быстрому старту](https://angular.io/docs/ts/latest/quickstart.html) от команды разработчиков Angular, чтобы начать изучение прямо сейчас! 7 | 8 | [Источник](http://typescript-lang.ru/docs/tutorials/Angular%202.html) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-handbook", 3 | "version": "1.0.0", 4 | "description": "The TypeScript Handbook is a comprehensive guide to the TypeScript language", 5 | "main": "none", 6 | "scripts": { 7 | "test": "node lint.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/Microsoft/TypeScript-Handbook.git" 12 | }, 13 | "author": "", 14 | "license": "Apache-2.0", 15 | "bugs": { 16 | "url": "https://github.com/Microsoft/TypeScript-Handbook/issues" 17 | }, 18 | "homepage": "https://github.com/Microsoft/TypeScript-Handbook#readme", 19 | "devDependencies": { 20 | "glob": "^5.0.15", 21 | "markdownlint": "latest" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /pull_request_template.md: -------------------------------------------------------------------------------- 1 | 16 | 17 | Fixes # 18 | -------------------------------------------------------------------------------- /pages/declaration files/templates/global-plugin.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for [~НАЗВАНИЕ БИБЛИОТЕКИ~] [~НЕОБЯЗАТЕЛЬНЫЙ НОМЕР ВЕРСИИ~] 2 | // Project: [~НАЗВАНИЕ ПРОЕКТА~] 3 | // Definitions by: [~ВАШЕ ИМЯ~] <[~ВАШ АДРЕС В ИНТЕРНЕТЕ~]> 4 | 5 | /*~ Этот шаблон показывает, как создать глобальный плагин */ 6 | 7 | /*~ Напишите объявление для исходного типа и добавьте новые члены. 8 | *~ Например, здесь к встроенному типу `number` добавляется метод 9 | *~ 'toBinaryString' с двумя перегрузками 10 | */ 11 | interface Number { 12 | toBinaryString(opts?: MyLibrary.BinaryFormatOptions): string; 13 | toBinaryString(callback: MyLibrary.BinaryFormatCallback, opts?: MyLibrary.BinaryFormatOptions): string; 14 | } 15 | 16 | /*~ Если нужно объявить несколько типов, поместите их в пространство имен, чтобы 17 | *~ сократить добавления к глобальному пространству имен 18 | */ 19 | declare namespace MyLibrary { 20 | type BinaryFormatCallback = (n: number) => string; 21 | interface BinaryFormatOptions { 22 | prefix?: string; 23 | padding: number; 24 | } 25 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | Этот репозиторий является переводом [TypeScript Handbook](https://github.com/Microsoft/TypeScript-Handbook). 4 | На данный момент перевод будет сделан для текущего импортированного коммита из официального репозитория (d07879c7c8d53990f732338c3a66caaf7592d37d). 5 | Далее правки руководства будут вноситься для новых коммитов. 6 | 7 | **Контрибьютеры будут вознаграждаться из donate фонда. Если в вашей компании заинтересованы в развитии Typescript, вы можете пополнить фонд. При создании вашего pull request отправьте мне на email kiselevgeorgy@gmail.com номер вашего Webmoney WMR или мобильного телефона и я перечислю вам вознаграждение из расчета 200 руб. за тысячу символов.** 8 | 9 | Если вы хотите принять участие, создайте issue с названием одной из тем, которой соответствует один из файлов документации (например, Basic Types, Advanced Types etc.) и в соответствующей ветке делайте перевод. Таким образом будет исключена возможность двойной работы. 10 | 11 | Рекоммендуется принимать участие только в случае вашей уверенности в хорошем качестве перевода. 12 | 13 | ## Housekeeping 14 | 15 | Ваш пул-реквест должен: 16 | 17 | * Включать краткое описание изменений, которые вносятся. 18 | -------------------------------------------------------------------------------- /pages/declaration files/templates/module-plugin.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for [~НАЗВАНИЕ БИБЛИОТЕКИ~] [~НЕОБЯЗАТЕЛЬНЫЙ НОМЕР ВЕРСИИ~] 2 | // Project: [~НАЗВАНИЕ ПРОЕКТА~] 3 | // Definitions by: [~ВАШЕ ИМЯ~] <[~ВАШ АДРЕС В ИНТЕРНЕТЕ~]> 4 | 5 | /*~ Это шаблон плагина модуля. Его нужно переименовать в index.d.ts 6 | *~ и поместить в папку с тем же именем, что и имя модуля. 7 | *~ Например, если вы создаете файл для "super-greeter", то этот файл 8 | *~ должен называться "super-greeter/index.d.ts" 9 | */ 10 | 11 | /*~ В этой строке импортируйте модуль, который дополняет этот плагин */ 12 | import * as m from 'someModule'; 13 | 14 | /*~ Если необходимо, можно экспортировать и другие модули */ 15 | import * as other from 'anotherModule'; 16 | 17 | /*~ Здесь объявите такой же модуль, что экспортированный выше */ 18 | declare module 'someModule' { 19 | /*~ Внутри него добавьте новые функции, классы или переменные. 20 | *~ Можно использовать типы, которые не были экспортированы из исходного модуля */ 21 | export function theNewMethod(x: m.foo): other.bar; 22 | 23 | /*~ Также можно добавлять новые свойства к существующим интерфейсам 24 | *~ из оригинального модуля, создавая дополнения интефейсов */ 25 | export interface SomeModuleOptions { 26 | someModuleSetting?: string; 27 | } 28 | 29 | /*~ Можно объявлять новые типы, которые будут работать так же, словно 30 | *~ объявленные в оригинальном модуле */ 31 | export interface MyModulePluginOptions { 32 | size: number; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pages/declaration files/templates/global-modifying-module.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for [~НАЗВАНИЕ БИБЛИОТЕКИ~] [~НЕОБЯЗАТЕЛЬНЫЙ НОМЕР ВЕРСИИ~] 2 | // Project: [~НАЗВАНИЕ ПРОЕКТА~] 3 | // Definitions by: [~ВАШЕ ИМЯ~] <[~ВАШ АДРЕС В ИНТЕРНЕТЕ~]> 4 | 5 | /*~ Это шаблон модуля, изменяющего глобальные переменные. Его нужно переименовать в index.d.ts 6 | *~ и поместить в папку с тем же именем, что и имя модуля. 7 | *~ Например, если вы создаете файл для "super-greeter", то этот файл 8 | *~ должен называться "super-greeter/index.d.ts" 9 | */ 10 | 11 | /*~ Замечание: если данный модуль может вызываться как функция или конструироваться, 12 | *~ то вам нужно объединить написанное здесь с тем, что находится в шаблонах 13 | *~ module-class или module-function 14 | */ 15 | 16 | declare global { 17 | /*~ Здесь объявите то, что будет находиться в глобальном пространстве имен, 18 | *~ или дополнять существующие в глобальном пространстве имен объявления 19 | */ 20 | interface String { 21 | fancyFormat(opts: StringFormatOptions): string; 22 | } 23 | } 24 | 25 | /*~ Если модуль экспортирует типы или значения, запишите их как обычно */ 26 | export interface StringFormatOptions { 27 | fancinessLevel: number; 28 | } 29 | 30 | /*~ Для примера: объявление метода модуля (вдобавок к его воздействию на 31 | *~ глобальную область видимости) 32 | */ 33 | export function doSomething(): void; 34 | 35 | /*~ Если модуль ничего не экспортирует, то понадобится эта строка. Иначе удалите ее */ 36 | export {}; 37 | -------------------------------------------------------------------------------- /README.md~: -------------------------------------------------------------------------------- 1 | # Руководство TypeScript на русском 2 | 3 | [![Build Status](https://travis-ci.org/Microsoft/TypeScript-Handbook.svg)](https://travis-ci.org/Microsoft/TypeScript-Handbook) 4 | 5 | Этот репозиторий является переводом [TypeScript Handbook](https://github.com/Microsoft/TypeScript-Handbook). 6 | На данный момент перевод будет сделан для текущего импортированного коммита из официального репозитория (d07879c7c8d53990f732338c3a66caaf7592d37d). 7 | Далее правки руководства будут вноситься для новых коммитов. 8 | 9 | 10 | **Контрибьютеры будут вознаграждаться из donate фонда. Если в вашей компании заинтересованы в развитии Typescript, вы можете пополнить фонд. При создании вашего pull request отправьте мне на email kiselevgeorgy@gmail.com или в личные сообщения [ВКонтакте](http://vk.com/georgykiselev) номер вашего Webmoney WMR или мобильного телефона и я перечислю вам вознаграждение из расчета 250 руб. за тысячу символов.** 11 | 12 | Если вы хотите принять участие, создайте issue с названием одной из тем, которой соответствует один из файлов документации (например, Basic Types, Advanced Types etc.) и в соответствующей ветке делайте перевод. Таким образом будет исключена возможность двойной работы. 13 | 14 | Рекоммендуется принимать участие только в случае вашей уверенности в хорошем качестве перевода. 15 | Последнюю версию вы всегда сможете найти на сайте [документации Typescript на русском](http://typescript-lang.ru/docs/). 16 | 17 | 18 | 19 | 20 | [Официальная спецификация языка](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md). 21 | -------------------------------------------------------------------------------- /pages/declaration files/templates/module.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for [~НАЗВАНИЕ БИБЛИОТЕКИ~] [~НЕОБЯЗАТЕЛЬНЫЙ НОМЕР ВЕРСИИ~] 2 | // Project: [~НАЗВАНИЕ ПРОЕКТА~] 3 | // Definitions by: [~ВАШЕ ИМЯ~] <[~ВАШ АДРЕС В ИНТЕРНЕТЕ~]> 4 | 5 | /*~ Это шаблон модуля. Его нужно переименовать в index.d.ts 6 | *~ и поместить в папку с тем же именем, что и имя модуля. 7 | *~ Например, если вы создаете файл для "super-greeter", то этот файл 8 | *~ должен называться "super-greeter/index.d.ts" 9 | */ 10 | 11 | /*~ Если это UMD-модуль, который предоставляет глобальную переменную 'myClassLib' 12 | *~ при загрузке в окружении без загрузчика модулей, объявите эту переменную здесь. 13 | *~ В противном случае удалите это объявление. 14 | */ 15 | export as namespace myLib; 16 | 17 | /*~ Если у этого модуля есть методы, объявите их как функции вот так: 18 | */ 19 | export function myMethod(a: string): string; 20 | export function myOtherMethod(a: number): number; 21 | 22 | /*~ Можно объявить типы, которые будут доступны через импорт */ 23 | export interface someType { 24 | name: string; 25 | length: number; 26 | extras?: string[]; 27 | } 28 | 29 | /*~ Свойства модуля можно объявлять c помощью const, let или var */ 30 | export const myField: number; 31 | 32 | /*~ Если существуют типы, свойства или методы модуля, доступные через точку, 33 | *~ объявите их внутри пространства имен */ 34 | export namespace subProp { 35 | /*~ Например, с этим объявлением можно написать: 36 | *~ import { subProp } from 'yourModule'; 37 | *~ subProp.foo(); 38 | *~ или 39 | *~ import * as yourMod from 'yourModule'; 40 | *~ yourMod.subProp.foo(); 41 | */ 42 | export function foo(): void; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /pages/declaration files/Consumption.md: -------------------------------------------------------------------------------- 1 | В TypeScript версии 2.0 стало значительно проще находить, получать и использовать файлы объявлений. 2 | Данный раздел подробно описывает, как все это делается. 3 | 4 | # Скачивание 5 | 6 | Получение файлов объявлений в TypeScript 2.0 и выше не требует никаких инструментов, кроме npm. 7 | 8 | Например, чтобы получить объявления для `lodash`, требуется всего одна команда: 9 | 10 | ```cmd 11 | npm install --save @types/lodash 12 | ``` 13 | 14 | # Использование 15 | 16 | После этого можно без проблем использовать библиотеку `lodash` в TypeScript-коде. 17 | Это работает как для модулей, так и для глобального кода. 18 | 19 | К примеру, как только объявления типов были установлены с помощью `npm install`, можно использовать `import` и написать: 20 | 21 | ```ts 22 | import * as _ from "lodash"; 23 | _.padStart("Привет, TypeScript!", 20, " "); 24 | ``` 25 | 26 | или, если модули не используются, просто задействовать глобальную переменную `_`. 27 | 28 | ```ts 29 | _.padStart("Привет, TypeScript!", 20, " "); 30 | ``` 31 | 32 | # Поиск 33 | 34 | Как правило, в `npm` пакеты с объявлениями типов имеют то же имя, что и сам пакет библиотеки, но с префиксом `@types/` в начале. Однако, если необходимо, можно посетить [https://aka.ms/types](https://aka.ms/types) и найти там пакет для своей любимой библиотеки. 35 | 36 | > Замечание: если необходимого файла объявлений нет, то вы всегда можете сделать свой вклад и помочь следующему разработчику, которому понадобится эта библиотека. 37 | > См. [руководство по принятию участия в DefinitelyTyped](http://definitelytyped.org/guides/contributing.html) для большей информации. 38 | 39 | [Источник](http://typescript-lang.ru/docs/declaration%20files/Consumption.html) -------------------------------------------------------------------------------- /pages/declaration files/templates/module-class.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for [~НАЗВАНИЕ БИБЛИОТЕКИ~] [~НЕОБЯЗАТЕЛЬНЫЙ НОМЕР ВЕРСИИ~] 2 | // Project: [~НАЗВАНИЕ ПРОЕКТА~] 3 | // Definitions by: [~ВАШЕ ИМЯ~] <[~ВАШ АДРЕС В ИНТЕРНЕТЕ~]> 4 | 5 | /*~ Это шаблон модуля, который является классом. Его нужно переименовать в index.d.ts 6 | *~ и поместить в папку с тем же именем, что и имя модуля. 7 | *~ Например, если вы создаете файл для "super-greeter", то этот файл 8 | *~ должен называться "super-greeter/index.d.ts" 9 | */ 10 | 11 | /*~ Обратите внимание, что ES6-модули не могут напрямую экспортировать объекты. 12 | *~ Этот файл следует импортировать, используя CommonJS: 13 | *~ import x = require('someLibrary'); 14 | *~ 15 | *~ Обратитесь к документации, чтобы узнать о распространенных способах 16 | *~ обхода данного ограничения для ES6-модулей. 17 | */ 18 | 19 | /*~ Если это UMD-модуль, который предоставляет глобальную переменную 'myClassLib' 20 | *~ при загрузке в окружении без загрузчика модулей, объявите эту переменную здесь. 21 | *~ В противном случае удалите это объявление. 22 | */ 23 | export as namespace myClassLib; 24 | 25 | /*~ Это объявление указывает, что функция-конструктор класса экспортируется 26 | *~ из данного файла 27 | */ 28 | export = MyClass; 29 | 30 | /*~ Добавьте в этот класс методы и свойства данного модуля */ 31 | declare class MyClass { 32 | constructor(someParam?: string); 33 | 34 | someProperty: string[]; 35 | 36 | myMethod(opts: MyClass.MyClassMethodOptions): number; 37 | } 38 | 39 | /*~ Если этот модуль должен предоставлять типы, то их можно поместить 40 | *~ в этот блок 41 | */ 42 | declare namespace MyClass { 43 | export interface MyClassMethodOptions { 44 | width?: number; 45 | height?: number; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /pages/declaration files/templates/global.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for [~НАЗВАНИЕ БИБЛИОТЕКИ~] [~НЕОБЯЗАТЕЛЬНЫЙ НОМЕР ВЕРСИИ~] 2 | // Project: [~НАЗВАНИЕ ПРОЕКТА~] 3 | // Definitions by: [~ВАШЕ ИМЯ~] <[~ВАШ АДРЕС В ИНТЕРНЕТЕ~]> 4 | 5 | /*~ Если библиотека может быть вызвана (например, как myLib(3)), 6 | *~ добавьте здесь сигнатуры вызова. 7 | *~ В противном случае удалите эту секцию. 8 | */ 9 | declare function myLib(a: string): string; 10 | declare function myLib(a: number): number; 11 | 12 | /*~ Если нужно, чтобы имя этой библиотеки было корректным именем типа, 13 | *~ это можно сделать здесь. 14 | *~ 15 | *~ Например, это позволяет написать 'var x: myLib'; 16 | *~ Убедитесь, что это имеет смысл! Если нет, просто 17 | *~ удалите это объявление и добавляйте типы в пространство имен ниже 18 | */ 19 | interface myLib { 20 | name: string; 21 | length: number; 22 | extras?: string[]; 23 | } 24 | 25 | /*~ Если библиотека имеет свойства, доступные через глобальную переменную 26 | *~ поместите их здесь. 27 | *~ Также здесь можно поместить типы (интерфейсы и псевдонимы типов). 28 | */ 29 | declare namespace myLib { 30 | //~ Можно написать 'myLib.timeout = 50;' 31 | let timeout: number; 32 | 33 | //~ Можно получить доступ к 'myLib.version', но не изменить 34 | const version: string; 35 | 36 | //~ Здесь какой-нибудь класс, объекты которого можно 37 | //~ создать как 'let c = new myLib.Cat(42)' 38 | //~ или ссылаться на него, например 'function f(c: myLib.Cat) { ... } 39 | class Cat { 40 | constructor(n: number); 41 | 42 | //~ Можно читать значение 'c.age' экземпляра 'Cat' 43 | readonly age: number; 44 | 45 | //~ Можно вызвать 'c.purr()' на экземпляре 'Cat' 46 | purr(): void; 47 | } 48 | 49 | //~ Можно объявить переменную как 50 | //~ 'var s: myLib.CatSettings = { weight: 5, name: "Maru" };' 51 | interface CatSettings { 52 | weight: number; 53 | name: string; 54 | tailLength?: number; 55 | } 56 | 57 | //~ Можно написать 'const v: myLib.VetID = 42;' 58 | //~ или 'const v: myLib.VetID = "bob";' 59 | type VetID = string | number; 60 | 61 | //~ Можно вызвать как 'myLib.checkCat(c)' или 'myLib.checkCat(c, v);' 62 | function checkCat(c: Cat, s?: VetID); 63 | } 64 | -------------------------------------------------------------------------------- /pages/declaration files/templates/module-function.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for [~НАЗВАНИЕ БИБЛИОТЕКИ~] [~НЕОБЯЗАТЕЛЬНЫЙ НОМЕР ВЕРСИИ~] 2 | // Project: [~НАЗВАНИЕ ПРОЕКТА~] 3 | // Definitions by: [~ВАШЕ ИМЯ~] <[~ВАШ АДРЕС В ИНТЕРНЕТЕ~]> 4 | 5 | /*~ Это шаблон модуля, который является функцией. Его нужно переименовать в index.d.ts 6 | *~ и поместить в папку с тем же именем, что и имя модуля. 7 | *~ Например, если вы создаете файл для "super-greeter", то этот файл 8 | *~ должен называться "super-greeter/index.d.ts" 9 | */ 10 | 11 | /*~ Обратите внимание, что ES6-модули не могут напрямую экспортировать вызываемые функции. 12 | *~ Этот файл следует импортировать, используя CommonJS: 13 | *~ import x = require('someLibrary'); 14 | *~ 15 | *~ Обратитесь к документации, чтобы узнать о распространенных способах 16 | *~ обхода данного ограничения для ES6-модулей. 17 | */ 18 | 19 | /*~ Если это UMD-модуль, который предоставляет глобальную переменную 'myClassLib' 20 | *~ при загрузке в окружении без загрузчика модулей, объявите эту переменную здесь. 21 | *~ В противном случае удалите это объявление. 22 | */ 23 | export as namespace myFuncLib; 24 | 25 | /*~ Это объявление указывает, что эта функция экспортируется 26 | *~ из данного файла 27 | */ 28 | export = MyFunction; 29 | 30 | /*~ Этот пример показывает, как добавить перегрузки к экспортируемой функции */ 31 | declare function MyFunction(name: string): MyFunction.NamedReturnType; 32 | declare function MyFunction(length: number): MyFunction.LengthReturnType; 33 | 34 | /*~ Если этот модуль должен предоставлять типы, то их можно поместить 35 | *~ в этот блок. Зачастую требуется описать форму типа значения, возвращаемого 36 | *~ функцией; тип для этого должен быть объявлен здесь, как показано в примере. 37 | */ 38 | declare namespace MyFunction { 39 | export interface LengthReturnType { 40 | width: number; 41 | height: number; 42 | } 43 | export interface NamedReturnType { 44 | firstName: string; 45 | lastName: string; 46 | } 47 | 48 | /*~ Если у модуля также есть свойства, объявите их здесь. Например, данное 49 | *~ объявление указывает, что следующий код допустим: 50 | *~ import f = require('myFuncLibrary'); 51 | *~ console.log(f.defaultName); 52 | */ 53 | export const defaultName: string; 54 | export let defaultLength: number; 55 | } 56 | -------------------------------------------------------------------------------- /pages/declaration files/Introduction.md: -------------------------------------------------------------------------------- 1 | Это руководство предназначено для обучения написанию высококачественных файлов объявлений для TypeScript. 2 | 3 | Предполагается, что читатель на базовом уровне знаком с языком TypeScript. 4 | Если это не так, то для ознакомления с основными принципами, а особенно с типами и пространствами имен, рекомендуется прочесть [Руководство по TypeScript](https://www.typescriptlang.org/docs/handbook/basic-types.html). 5 | 6 | # Разделы 7 | 8 | Руководство разбито на следующие разделы. 9 | 10 | ## Структуры библиотек 11 | 12 | Руководство по [структурам библиотек](./Library Structures.html) поможет понять распространенные форматы библиотек и то, как писать правильные файлы объявлений для каждого формата. 13 | Если вы редактируете уже существующий файл, то скорее всего, данный раздел читать не обязательно. 14 | Авторы новых файлов объявлений должны прочесть данный раздел, чтобы верно понять, как формат библиотеки влияет на написание файлов объявлений. 15 | 16 | ## "Как можно" и "Как нельзя" 17 | 18 | Многих часто встречающихся ошибок в файлах объявлений можно избежать. 19 | Раздел ["Как можно" и "Как нельзя"](./Do's and Don'ts.html) указывает на распространенные ошибки, описывает, как их находить и исправлять. 20 | Этот раздел должны прочесть все, чтобы научиться не допускать распространенных ошибок. 21 | 22 | ## На примере 23 | 24 | Зачастую требуется создать файл объявлений, когда есть только примеры использования нужной библиотеки. 25 | Раздел [На примере](./By Example.html) показывает часто встречающиеся шаблоны API и то, как они описываются в файлах объявлений. 26 | Данный раздел предназначен для новичков в TypeScript, которые, возможно, еще не знакомы со всеми конструкциями языка. 27 | 28 | ## Глубокое погружение 29 | 30 | Раздел для бывалых разработчиков, интересующихся, как работают файлы объявлений "под капотом". [Данный раздел](./Deep Dive.html) объясняет множество сложных принципов написания объявлений, и показывает, как использовать их для создания более ясных и простых файлов объявлений. 31 | 32 | ## `/templates` 33 | 34 | В директории [`templates`](https://github.com/Microsoft/TypeScript-Handbook-RU/tree/master/pages/declaration%20files/templates) находятся файлы объявлений, которые могут послужить отправной точкой для создания нового файла объявлений. 35 | См. документацию касательно [структур библиотек](./Library Structures.html), чтобы понять, какой шаблон использовать. 36 | 37 | ## Публикация в npm 38 | 39 | Раздел [Публикация](./Publishing.html) объясняет, как опубликовать файлы объявлений для npm-пакета и управлять зависимостями. 40 | 41 | ## Поиск и установка файлов объявлений 42 | 43 | Для пользователей JavaScript-библиотек предназначен раздел [Использование](./Consumption.html), который предлагает простые шаги для нахождения и установки необходимых файлов объявлений. 44 | 45 | [Источник](http://typescript-lang.ru/docs/declaration%20files/Introduction.html) -------------------------------------------------------------------------------- /pages/Iterators and Generators.md: -------------------------------------------------------------------------------- 1 | # Итерируемые элементы 2 | 3 | Итерируемым является такой объект, который содержит реализацию свойства [`Symbol.iterator`](Symbols.html#symboliterator). 4 | Некоторые встроенный типы, такие как `Array`, `Map`, `Set`, `String`, `Int32Array`, `Uint32Array` и т.д., содержат уже реализованное свойство `Symbol.iterator`. 5 | Взятая от объекта функция `Symbol.iterator` должна возвратить список значений для организации цикла. 6 | 7 | ## Оператор `for..of` 8 | 9 | Для перебора итерируемого объекта в цикле `for..of`, на нём вызывается свойство `Symbol.iterator`. 10 | Вот простой пример прохождения цикла `for..of` по массиву: 11 | 12 | ```ts 13 | let someArray = [1, "string", false]; 14 | 15 | for (let entry of someArray) { 16 | console.log(entry); // 1, "string", false 17 | } 18 | ``` 19 | 20 | ### `for..of` против `for..in` 21 | 22 | И `for..of`, и `for..in` используются для перебора списков. При этом значения, по которым выполняется обход, различаются. `for..in` возвращает список *ключей* итерируемого объекта, когда как `for..of` возвращает список *значений* его числовых свойств. 23 | 24 | Следующий пример демонстрирует различие: 25 | 26 | ```ts 27 | let list = [4, 5, 6]; 28 | 29 | for (let i in list) { 30 | console.log(i); // "0", "1", "2", 31 | } 32 | 33 | for (let i of list) { 34 | console.log(i); // "4", "5", "6" 35 | } 36 | ``` 37 | 38 | Ещё одно различие заключается в том, что `for..in` может использоваться для обхода любого объекта, являясь средством инспектирования его свойств. 39 | А `for..of` в первую очередь предназначен для получения значений. Такие встроенные объекты, как `Map` и `Set`, реализуют свойство `Symbol.iterator`, предоставляя с его помощью доступ к хранимым значениям. 40 | 41 | ```ts 42 | let pets = new Set(["Cat", "Dog", "Hamster"]); 43 | pets["species"] = "mammals"; 44 | 45 | for (let pet in pets) { 46 | console.log(pet); // "species" 47 | } 48 | 49 | for (let pet of pets) { 50 | console.log(pet); // "Cat", "Dog", "Hamster" 51 | } 52 | ``` 53 | 54 | ### Генерация кода 55 | 56 | #### Соответствие ES5 и ES3 57 | 58 | Если целевым стандартом являются ES5 или ES3, допускается использование итераторов только для объектов типа `Array`. 59 | Попытка обхода объектов других типов с помощью `for..of` будет ошибкой, даже если эти объекты реализуют свойство `Symbol.iterator`. 60 | 61 | Компилятор сгенерирует простой цикл `for` вместо цикла `for..of`, например: 62 | 63 | ```ts 64 | let numbers = [1, 2, 3]; 65 | for (let num of numbers) { 66 | console.log(num); 67 | } 68 | ``` 69 | 70 | будет сгенерировано в виде: 71 | 72 | ```js 73 | var numbers = [1, 2, 3]; 74 | for (var _i = 0; _i < numbers.length; _i++) { 75 | var num = numbers[_i]; 76 | console.log(num); 77 | } 78 | ``` 79 | 80 | #### Соответствие ECMAScript 2015 и выше 81 | 82 | В том случае, если целевым стандартом является ECMAScipt 2015, компилятор сгенерирует циклы `for..of` в соответствии со встроенной в движок реализацией итераторов. 83 | 84 | [Источник](http://typescript-lang.ru/docs/Iterators%20and%20Generators.html) -------------------------------------------------------------------------------- /pages/Nightly Builds.md: -------------------------------------------------------------------------------- 1 | A nightly build from the [TypeScript's `master`](https://github.com/Microsoft/TypeScript/tree/master) branch is published by midnight PST to NPM and NuGet. 2 | Here is how you can get it and use it with your tools. 3 | 4 | ## Using npm 5 | 6 | ```shell 7 | npm install -g typescript@next 8 | ``` 9 | 10 | ## Using NuGet with MSBuild 11 | 12 | > Note: You'll need to configure your project to use the NuGet packages. 13 | Please see [Configuring MSBuild projects to use NuGet](https://github.com/Microsoft/TypeScript/wiki/Configuring-MSBuild-projects-to-use-NuGet) for more information. 14 | 15 | The nightlies are available on [www.myget.org](https://www.myget.org/gallery/typescript-preview). 16 | 17 | There are two packages: 18 | 19 | * `Microsoft.TypeScript.Compiler`: Tools only (`tsc.exe`, `lib.d.ts`, etc.) . 20 | * `Microsoft.TypeScript.MSBuild`: Tools as above, as well as MSBuild tasks and targets (`Microsoft.TypeScript.targets`, `Microsoft.TypeScript.Default.props`, etc.) 21 | 22 | ## Updating your IDE to use the nightly builds 23 | 24 | You can also update your IDE to use the nightly drop. 25 | First you will need to install the package through npm. 26 | You can either install the npm package globally or to a local `node_modules` folder. 27 | 28 | The rest of this section assumes `typescript@next` is already installed. 29 | 30 | ### Visual Studio Code 31 | 32 | Update `.vscode/settings.json` with the following: 33 | 34 | ```json 35 | "typescript.tsdk": "/node_modules/typescript/lib" 36 | ``` 37 | 38 | More information is available at [VSCode documentation](https://code.visualstudio.com/Docs/languages/typescript#_using-newer-typescript-versions). 39 | 40 | ### Sublime Text 41 | 42 | Update the `Settings - User` file with the following: 43 | 44 | ```json 45 | "typescript_tsdk": "/node_modules/typescript/lib" 46 | ``` 47 | 48 | More information is available at the [TypeScript Plugin for Sublime Text installation documentation](https://github.com/Microsoft/TypeScript-Sublime-Plugin#installation). 49 | 50 | ### Visual Studio 2013 and 2015 51 | 52 | > Note: Most changes do not require you to install a new version of the VS TypeScript plugin. 53 | 54 | The nightly build currently does not include the full plugin setup, but we are working on publishing an installer on a nightly basis as well. 55 | 56 | 1. Download the [VSDevMode.ps1](https://github.com/Microsoft/TypeScript/blob/master/scripts/VSDevMode.ps1) script. 57 | 58 | > Also see our wiki page on [using a custom language service file](https://github.com/Microsoft/TypeScript/wiki/Dev-Mode-in-Visual-Studio#using-a-custom-language-service-file). 59 | 60 | 2. From a PowerShell command window, run: 61 | 62 | For VS 2015: 63 | ```posh 64 | VSDevMode.ps1 14 -tsScript /node_modules/typescript/lib 65 | ``` 66 | 67 | For VS 2013: 68 | 69 | ```posh 70 | VSDevMode.ps1 12 -tsScript /node_modules/typescript/lib 71 | ``` 72 | 73 | [Источник](http://typescript-lang.ru/docs/Nightly%20Builds.html) -------------------------------------------------------------------------------- /pages/Symbols.md: -------------------------------------------------------------------------------- 1 | # Введение 2 | 3 | В ECMAScript 2015 введен тип `symbol` (символ) — примитивный тип данных, такой же, как `number` и `string`. 4 | 5 | Значения типа `symbol` создаются с помощью вызова конструктора `Symbol`. 6 | 7 | ```ts 8 | let sym1 = Symbol(); 9 | 10 | let sym2 = Symbol("key"); // Необязательный строковый ключ 11 | ``` 12 | 13 | Символы неизменяемы и уникальны. 14 | 15 | ```ts 16 | let sym2 = Symbol("key"); 17 | let sym3 = Symbol("key"); 18 | 19 | sym2 === sym3; // false, символы уникальны 20 | ``` 21 | 22 | Подобно строкам, символы можно использовать как ключи для свойств объекта. 23 | 24 | ```ts 25 | let sym = Symbol(); 26 | 27 | let obj = { 28 | [sym]: "value" 29 | }; 30 | 31 | console.log(obj[sym]); // "value" 32 | ``` 33 | 34 | Символы можно использовать вместе с вычисляемыми свойствами, чтобы объявлять свойства объектов и члены классов: 35 | 36 | ```ts 37 | const getClassNameSymbol = Symbol(); 38 | 39 | class C { 40 | [getClassNameSymbol](){ 41 | return "C"; 42 | } 43 | } 44 | 45 | let c = new C(); 46 | let className = c[getClassNameSymbol](); // "C" 47 | ``` 48 | 49 | # Заранее определенные символы 50 | 51 | Кроме символов, определяемых пользователем, существуют заранее определенные встроенные символы. 52 | Встроенные символы нужны для отражения внутреннего поведения языка. 53 | 54 | Список заранее определенных символов: 55 | 56 | ## `Symbol.hasInstance` 57 | 58 | Метод, который определяет, распознает ли объект конструктора переданный объект как экземпляр этого конструктора. Вызывается оператором `instanceof`. 59 | 60 | ## `Symbol.isConcatSpreadable` 61 | 62 | Логическое значение, означающее, должен ли объект раскладываться на элементы массива при использовании с `Array.prototype.concat`. 63 | 64 | ## `Symbol.iterator` 65 | 66 | Метод, который возвращает итератор по умолчанию для объекта. Вызывается конструкцией `for-of`. 67 | 68 | ## `Symbol.match` 69 | 70 | Метод для регулярных выражений, который сопоставляет регулярное выражение со строкой. Вызывается методом `String.prototype.match`. 71 | 72 | ## `Symbol.replace` 73 | 74 | Метод для регулярных выражений, который заменяет совпавшие подстроки в строке. Вызывается методом `String.prototype.replace`. 75 | 76 | ## `Symbol.search` 77 | 78 | Метод для регулярных выражений, который возвращает позицию в строке, где находится совпадение с регулярным выражением. Вызывается методом `String.prototype.search`. 79 | 80 | ## `Symbol.species` 81 | 82 | Свойство, содержащее функцию, которая служит в качестве конструктора для унаследованных объектов. 83 | 84 | ## `Symbol.split` 85 | 86 | Метод для регулярных выражений, который разбивает строку по позициям совпадений с регулярным выражением. 87 | Вызывается методом `String.prototype.split`. 88 | 89 | ## `Symbol.toPrimitive` 90 | 91 | Метод, который превращает объект в соответствующее примитивное значение. 92 | Вызывается абстрактной операцией `ToPrimitive`. 93 | 94 | ## `Symbol.toStringTag` 95 | 96 | Строковое значение, которое используется для создания строкового значения по умолчанию, описывающего объект. 97 | Вызывается встроенным методом `Object.prototype.toString`. 98 | 99 | ## `Symbol.unscopables` 100 | 101 | Объект, имена собственных свойств которого — это имена свойств, привязки к которым не включаются в окружение, создаваемое конструкцией `with` для соответствующих объектов. 102 | 103 | [Источник](http://typescript-lang.ru/docs/Symbols.html) -------------------------------------------------------------------------------- /pages/Type Inference.md: -------------------------------------------------------------------------------- 1 | # Введение 2 | 3 | В этой главе обсуждается выведение типов в TypeScript. 4 | А именно, мы расскажем, где и как выводятся типы. 5 | 6 | # Основы 7 | 8 | В TypeScript существует несколько мест, где используется выведение типов для того, чтобы получить информацию о типах без явного ее указания. К примеру, в этом коде 9 | 10 | ```ts 11 | let x = 3; 12 | ``` 13 | 14 | Тип переменной `x` выводится в `number`. 15 | Выведение такого рода происходит при инициализации переменных и членов, присваивании параметрам значений по умолчанию и определении типа возвращаемого значения функции. 16 | 17 | В большинстве случаев выведение типов довольно прямолинейно. 18 | В последующих разделах мы опишем несколько тонкостей этого процесса. 19 | 20 | # Наилучший общий тип 21 | 22 | Когда выведение делается на основании нескольких выражений, их типы используются для нахождения "наилучшего общего типа". К примеру, 23 | 24 | ```ts 25 | let x = [0, 1, null]; 26 | ``` 27 | 28 | Чтобы вывести тип `x` в этом случае, нужно проверить тип каждого элемента в массиве. 29 | В данном случае есть два варианта для типа массива: `number` и `null`. 30 | Алгоритм нахождения наилучшего общего типа проверяет каждый тип-кандидат, и выбирает тот, который совместим со всеми остальными. 31 | 32 | Поскольку наилучший общий тип должен быть выбран из предоставленных типов, бывают случаи, когда типы имеют общую для всех структуру, но ни один из них не является базовым для всех остальных. К примеру: 33 | 34 | ```ts 35 | // Здесь Rhino — носорог, Elephant — слон, а Snake — змея 36 | let zoo = [new Rhino(), new Elephant(), new Snake()]; 37 | ``` 38 | 39 | В идеале, хотелось бы, чтобы тип zoo был выведен как `Animal[]` (то есть массив объектов класса `Animal` — животное). Но, так как в массиве нет ни одного объекта, который бы имел класс именно `Animal`, компилятор не способен получить такой результат. 40 | Чтобы исправить это, придется явно указать тип, если ни один объект не имеет тип, базовый для всех остальных: 41 | 42 | ```ts 43 | let zoo: Animal[] = [new Rhino(), new Elephant(), new Snake()]; 44 | ``` 45 | 46 | Если компилятору не удается найти наилучший общий тип, результатом выведения будет тип пустого объекта, то есть `{}`. 47 | Так как у такого типа нет членов, попытка использовать какие-либо его свойства приведет к ошибке. 48 | В результате такого выведения по-прежнему можно использовать объект, словно его тип неизвестен, и гарантировать безопасность типов в тех случаях, когда тип объекта не может быть найден неявно. 49 | 50 | # Контекстный тип 51 | 52 | В некоторых случаях выведение типов работает и в "другом направлении". 53 | Это называется "контекстной типизацией". Контекстная типизация происходит, когда о типе выражения можно сделать догадку на основании его положения. К примеру: 54 | 55 | ```ts 56 | window.onmousedown = function(mouseEvent) { 57 | console.log(mouseEvent.buton); //<- Ошибка 58 | }; 59 | ``` 60 | 61 | Для того, чтобы найти ошибку типов в этом примере, компилятор сначала использовал тип функции `Window.onmousedown`, чтобы вывести тип функционального выражения из правой части присваивания. 62 | После этого он смог вывести тип параметра `mouseEvent`. 63 | Если бы данное функциональное выражение находилось там, где его тип нельзя было бы вывести из контекста, тип параметра `mouseEvent` был бы `any`, и компилятор не выдал бы ошибки. 64 | 65 | Если выражение, тип которого был выведен из контекста, содержит явное указание типа, то выведенный контекстный тип игнорируется. 66 | То есть, если бы предыдущий пример был записан как: 67 | 68 | ```ts 69 | window.onmousedown = function(mouseEvent: any) { 70 | console.log(mouseEvent.buton); //<- Теперь ошибка не выдается 71 | }; 72 | ``` 73 | 74 | Явно указанный тип параметра в функциональном выражении будет иметь приоритет над контекстным типом. 75 | По этой причине компилятор не выдаст ошибки, поскольку контекстный тип не применяется. 76 | 77 | Контекстная типизация применяется во многих случаях. 78 | Как правило, это аргументы при вызове функций, правая часть присваивания, проверки типов, члены объектов и литералы массивов, а также инструкции `return`. 79 | Также контекстный тип используется в качестве кандидата в наилучший общий тип. К примеру: 80 | 81 | ```ts 82 | function createZoo(): Animal[] { 83 | return [new Rhino(), new Elephant(), new Snake()]; 84 | } 85 | ``` 86 | 87 | Здесь есть четыре кандидата на роль наилучшего общего типа: `Animal`, `Rhino`, `Elephant` и `Snake`. 88 | Алгоритм поиска наилучшего общего типа способен выбрать из них `Animal`. 89 | 90 | [Источник](http://typescript-lang.ru/docs/Type%20Inference.html) -------------------------------------------------------------------------------- /lint.js: -------------------------------------------------------------------------------- 1 | var markdownlint = require("markdownlint"); 2 | var glob = require("glob"); 3 | var fs = require("fs"); 4 | 5 | var inputFiles = glob.sync("**/*.md", { ignore: "node_modules/**/*" }); 6 | var options = { 7 | files: inputFiles, 8 | config: { 9 | MD001: false, // Header levels should only increment by one level at a time 10 | MD002: false, // First header should be a h1 header 11 | MD003: "atx", // Header style 12 | MD004: { style: "asterisk" }, // Unordered list style 13 | MD005: true, // Inconsistent indentation for list items at the same level 14 | MD006: true, // Consider starting bulleted lists at the beginning of the line 15 | MD007: { indent: 4 }, // Unordered list indentation 16 | MD009: true, // Trailing spaces 17 | MD010: true, // Hard tabs 18 | MD011: true, // Reversed link syntax 19 | MD012: true, // Multiple consecutive blank lines 20 | MD013: false, // Line length 21 | MD014: false, // Dollar signs used before commands without showing output 22 | MD018: true, // No space after hash on atx style header 23 | MD019: true, // Multiple spaces after hash on atx style header 24 | MD020: false, // No space inside hashes on closed atx style header 25 | MD021: false, // Multiple spaces inside hashes on closed atx style header 26 | MD022: true, // Headers should be surrounded by blank lines 27 | MD023: true, // Headers must start at the beginning of the line 28 | MD024: false, // Multiple headers with the same content 29 | MD025: false, // Multiple top level headers in the same document 30 | MD026: { punctuation: ".,;:!" }, // Trailing punctuation in header 31 | MD027: true, // Multiple spaces after blockquote symbol 32 | MD028: true, // Blank line inside blockquote 33 | MD029: { style: "ordered" }, // Ordered list item prefix 34 | MD030: true, // Spaces after list markers 35 | MD031: true, // Fenced code blocks should be surrounded by blank lines 36 | MD032: true, // Lists should be surrounded by blank lines 37 | MD033: false, // Inline HTML 38 | MD034: true, // Bare URL used 39 | MD035: "---", // Horizontal rule style 40 | MD036: false, // Emphasis used instead of a header 41 | MD037: true, // Spaces inside emphasis markers 42 | MD038: false, // Spaces inside code span elements 43 | MD039: true, // Spaces inside link text 44 | MD040: true, // Fenced code blocks should have a language specified 45 | MD041: false, // First line in file should be a top level header 46 | } 47 | }; 48 | 49 | var result = markdownlint.sync(options); 50 | console.log(result.toString()); 51 | 52 | var exitCode = 0; 53 | Object.keys(result).forEach(function (file) { 54 | var fileResults = result[file]; 55 | Object.keys(fileResults).forEach(function (rule) { 56 | var ruleResults = fileResults[rule]; 57 | exitCode += ruleResults.length; 58 | }); 59 | }); 60 | 61 | inputFiles.forEach(function(fileName) { 62 | var text = fs.readFileSync(fileName, "utf8") 63 | exitCode += checkForImproperlyIndentedFencedCodeBlocks(fileName, text); 64 | }) 65 | 66 | process.exit(exitCode); 67 | 68 | /** 69 | * @param {string} fileName 70 | * @param {string} text 71 | */ 72 | function checkForImproperlyIndentedFencedCodeBlocks(fileName, text) { 73 | var lines = text.split(/\r?\n/g); 74 | var numErrors = 0; 75 | 76 | for (var i = 0; i < lines.length; i++) { 77 | var line = lines[i]; 78 | var codeBlockMatch = line.match(/^(\s*)```\S+/); 79 | 80 | if (codeBlockMatch) { 81 | var startingColumn = codeBlockMatch[1].length; 82 | if (startingColumn === 0 || startingColumn === getCorrectStartingColumnForLine(lines, i)) { 83 | continue; 84 | } 85 | 86 | numErrors++; 87 | console.log(fileName + ": " + 88 | i + 1 + ": A fenced code block following a list item must be indented to the first non-whitespace character of the list item.") 89 | } 90 | } 91 | 92 | return numErrors; 93 | } 94 | 95 | /** 96 | * @param {string[]} line 97 | * @param {number} lineIndex 98 | */ 99 | function getCorrectStartingColumnForLine(lines, lineIndex) { 100 | for (var i = lineIndex - 1; i >= 0; i--) { 101 | var line = lines[i]; 102 | 103 | if (line.length === 0) { 104 | continue; 105 | } 106 | 107 | var m; 108 | if (m = line.match(/^\s*([\*\-]|(\d+\.))\s*/)) { 109 | return m[0].length; 110 | } 111 | if (m = line.match(/^(\s*)/)) { 112 | return m[0].length; 113 | } 114 | } 115 | 116 | return 0; 117 | } -------------------------------------------------------------------------------- /pages/Enums.md: -------------------------------------------------------------------------------- 1 | # Перечисления 2 | 3 | Перечисления позволяют определить набор именованных числовых констант. Они определяются используя ключевое слово `enum`. 4 | 5 | ```ts 6 | enum Direction { 7 | Up = 1, 8 | Down, 9 | Left, 10 | Right 11 | } 12 | ``` 13 | 14 | Тело перечисления состоит из нуля или более элементов. Элементы перечисления имеют численное значение ассоциированное с именем, и могут быть либо *константой*, либо могут быть *вычислены*. Элемент перечисления считается константой, если: 15 | 16 | * Он не имеет инициализатора, предшествующий элемент перечисления был константой. В этом случае значение текущего элемента перечисления будет равняться значению предшествующего элемента перечисления плюс единица. Исключением является первый элемент перечисления. Если элемент не имеет инициализатора, ему присваивается значение `0`. 17 | * Элемент перечисления инициализирован с константным выражением перечисления. Константное выражение перечисления - это подмножество TypeScript выражений, которое может быть полностью вычислено во время компиляции. Выражение является константным выражением перечисления, если оно является либо: 18 | * численным литералом 19 | * ссылкой к прежде определённому константному элементу перечисления (она может быть определёна в различных перечислениях). Если элемент определён в том же перечислении, на него можно сослаться, используя неквалифицированное имя. 20 | * константным выражением перечисления, взятым в круглые скобки 21 | * унарным оператором `+`, `-`, `~`, применённым к константному выражению перечисления 22 | * бинарным оператором `+`, `-`, `*`, `/`, `%`, `<<`, `>>`, `>>>`, `&`, `|`, `^` с константным выражением перечисления как операнд. Константное выражение перечисления, вычисляемое в `NaN` или `Infinity`, приводит к ошибке во время компиляции 23 | 24 | Во всех остальных случаях считается, что элемент перечисления вычисляем. 25 | 26 | ```ts 27 | enum FileAccess { 28 | // константные элементы 29 | None, 30 | Read = 1 << 1, 31 | Write = 1 << 2, 32 | ReadWrite = Read | Write, 33 | // вычисляемые элементы 34 | G = "123".length 35 | } 36 | ``` 37 | 38 | Перечисления - это действительные объекты, существующие во время выполнения. Одной из причин этого является способность поддерживать обратное отображение из значений перечисления к именам перечисления. 39 | 40 | ```ts 41 | enum Enum { 42 | A 43 | } 44 | let a = Enum.A; 45 | let nameOfA = Enum[Enum.A]; // "A" 46 | ``` 47 | 48 | компилируется в: 49 | 50 | ```js 51 | var Enum; 52 | (function (Enum) { 53 | Enum[Enum["A"] = 0] = "A"; 54 | })(Enum || (Enum = {})); 55 | var a = Enum.A; 56 | var nameOfA = Enum[Enum.A]; // "A" 57 | ``` 58 | 59 | В сгенерированном коде перечисление скомпилировано в объект, который хранит прямое (`имя` -> `значение`) и обратное (`значение` -> `имя`) отображения. Ссылки к элементам перечисления всегда выполняются как доступы к свойству и никогда не встраиваются. Во многих случаях это является правильным решением. Однако, иногда требования жёстче. Чтобы избежать оплаты стоимости дополнительного сгенерированного кода и косвенного обращения при получении доступа к значениям перечисления можно использовать константные перечисления. Константые перечисления определяются используя модификатор `const`, предшествующий ключевому слову `enum`. 60 | 61 | ```ts 62 | const enum Enum { 63 | A = 1, 64 | B = A * 2 65 | } 66 | ``` 67 | 68 | Константные перечисления могут только использовать константные выражения перечисления, и в отличие обычных перечислений они полностью удаляются в течение компиляции. Элементы константного перечисления встраиваются в местах использования. Это возможно, поскольку константные перечисления не могут иметь вычисляемых элементов. 69 | 70 | ```ts 71 | const enum Directions { 72 | Up, 73 | Down, 74 | Left, 75 | Right 76 | } 77 | 78 | let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right] 79 | ``` 80 | 81 | в сгенерированном коде превратится в 82 | 83 | ```js 84 | var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */]; 85 | ``` 86 | 87 | # Окружающие перечисления 88 | 89 | Окружающие перечисления используются для описания формы уже существующих перечислений. 90 | 91 | ```ts 92 | declare enum Enum { 93 | A = 1, 94 | B, 95 | C = 2 96 | } 97 | ``` 98 | 99 | Одно важное отличие между окружающим и не окружающим перечислениями в том, что в обычных перечислениях элементы, не имеющие инициализатора, считаются константными элементами. Для элемента не константного окружающего перечисления, не имеющего инициализатора, элемент считается вычисляемым. 100 | 101 | [Источник](http://typescript-lang.ru/docs/Enums.html) -------------------------------------------------------------------------------- /pages/Mixins.md: -------------------------------------------------------------------------------- 1 | # Введение 2 | 3 | Помимо принятой в ООП традиционной иерархии, существует способ создания классов из повторно используемых компонентов путем комбинирования более простых неполных классов. 4 | Возможно, вы знакомы с идеей примесей (англ. mixins) или типажей (англ. traits), используемых в таких языках, как Scala. Этот подход также получил некоторое распространение в сообществе пользователей JavaScript. 5 | 6 | # Пример примеси 7 | 8 | Ниже приведен код, демонстрирующий использование примесей в TypeScript. 9 | После примера последует его подробное объяснение. 10 | 11 | ```ts 12 | // Disposable (одноразовый) mixin 13 | class Disposable { 14 | isDisposed: boolean; 15 | dispose() { 16 | this.isDisposed = true; 17 | } 18 | 19 | } 20 | 21 | // Activatable (активируемый) mixin 22 | class Activatable { 23 | isActive: boolean; 24 | activate() { 25 | this.isActive = true; 26 | } 27 | deactivate() { 28 | this.isActive = false; 29 | } 30 | } 31 | 32 | class SmartObject implements Disposable, Activatable { 33 | constructor() { 34 | setInterval(() => console.log(this.isActive + " : " + this.isDisposed), 500); 35 | } 36 | 37 | interact() { 38 | this.activate(); 39 | } 40 | 41 | // Disposable 42 | isDisposed: boolean = false; 43 | dispose: () => void; 44 | // Activatable 45 | isActive: boolean = false; 46 | activate: () => void; 47 | deactivate: () => void; 48 | } 49 | applyMixins(SmartObject, [Disposable, Activatable]); 50 | 51 | let smartObj = new SmartObject(); 52 | setTimeout(() => smartObj.interact(), 1000); 53 | 54 | //////////////////////////////////////// 55 | // Где-то в вашей динамической библиотеке 56 | //////////////////////////////////////// 57 | 58 | function applyMixins(derivedCtor: any, baseCtors: any[]) { 59 | baseCtors.forEach(baseCtor => { 60 | Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { 61 | derivedCtor.prototype[name] = baseCtor.prototype[name]; 62 | }); 63 | }); 64 | } 65 | ``` 66 | 67 | # Разбор примера 68 | 69 | Код начинается с определения двух классов, которые и будут задействованы в качестве примесей. 70 | Каждый из них нацелен на демонстрацию определенной активности или возможности. 71 | Позже мы их смешаем, чтобы сформировать новый объединяющий их свойства класс. 72 | 73 | ```ts 74 | // Disposable mixin 75 | class Disposable { 76 | isDisposed: boolean; 77 | dispose() { 78 | this.isDisposed = true; 79 | } 80 | 81 | } 82 | 83 | // Activatable mixin 84 | class Activatable { 85 | isActive: boolean; 86 | activate() { 87 | this.isActive = true; 88 | } 89 | deactivate() { 90 | this.isActive = false; 91 | } 92 | } 93 | ``` 94 | 95 | Далее мы создадим новый класс, который будет объединять обе примеси. 96 | Давайте рассмотрим, как этого добиться: 97 | 98 | ```ts 99 | class SmartObject implements Disposable, Activatable { 100 | ``` 101 | 102 | Первое, на что вы могли обратить внимание, - вместо `extends` используется `implements`. 103 | Такой подход позволяет рассматривать классы как интерфейсы и использовать только типы Disposable и Activatable, а не их реализации. 104 | Получается, что реализацию мы должны будем создать в новом классе. 105 | Но проблема в том, что именно этого мы бы и хотели избежать при использовании примесей. 106 | 107 | Чтобы не делать реализации заново, мы создаем свойства-дублёры (stand-in properties), типы которых будут получены из соответствующих примесей. 108 | Компилятору достаточно, чтобы эти элементы были доступны динамически. 109 | Такой подход позволяет нам пользоваться преимуществами примесей, но при условии дополнительной нагрузки по учёту подобных нюансов. 110 | 111 | ```ts 112 | // Disposable 113 | isDisposed: boolean = false; 114 | dispose: () => void; 115 | // Activatable 116 | isActive: boolean = false; 117 | activate: () => void; 118 | deactivate: () => void; 119 | ``` 120 | 121 | В итоге мы соединяем наши примеси в классе, создавая полную реализацию. 122 | 123 | ```ts 124 | applyMixins(SmartObject, [Disposable, Activatable]); 125 | ``` 126 | 127 | В завершение напишем вспомогательную функцию, предназначенную для создания примесей. 128 | Она будет пробегать по свойствам примесей и копировать их в целевой элемент, заполняя свойства-дублёры их реализациями. 129 | 130 | ```ts 131 | function applyMixins(derivedCtor: any, baseCtors: any[]) { 132 | baseCtors.forEach(baseCtor => { 133 | Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { 134 | derivedCtor.prototype[name] = baseCtor.prototype[name]; 135 | }); 136 | }); 137 | } 138 | 139 | ``` 140 | 141 | [Источник](http://typescript-lang.ru/docs/Mixins.html) -------------------------------------------------------------------------------- /pages/declaration files/Publishing.md: -------------------------------------------------------------------------------- 1 | Теперь, когда вы, следуя шагам из этого руководства, создали файл объявлений, пришло время опубликовать его в npm. 2 | Есть два основных пути для этого: 3 | 4 | 1. включить объявления в npm-пакет 5 | 2. опубликовать в [организации @types](https://www.npmjs.com/~types) в npm. 6 | 7 | Если вы управляете пакетом, для которого собираетесь опубликовать объявления, то первый способ подойдет лучше всего. 8 | В этом случае объявления и JavaScript-код всегда будут вместе. 9 | 10 | # Включение объявлений в свой npm-пакет 11 | 12 | Если у пакета есть главный `.js`-файл, то в `package.json` нужно также указать главный файл с объявлениями. 13 | Для этого установите свойство `types`, которое должно указывать на файл объявлений. 14 | Например: 15 | 16 | ```json 17 | { 18 | "name": "awesome", 19 | "author": "Vandelay Industries", 20 | "version": "1.0.0", 21 | "main": "./lib/main.js", 22 | "types": "./lib/main.d.ts" 23 | } 24 | ``` 25 | 26 | Стоит отметить, что поле `"typings"` синонимично `"types"` и также может быть использовано. 27 | 28 | Также отметим, что если главный файл объявлений имеет имя `index.d.ts` и находится в корне директории пакета (рядом с `index.js`), то указывать свойство `"types"` не обязательно, хотя и желательно. 29 | 30 | ## Зависимости 31 | 32 | Все зависимости управляются npm. 33 | Убедитесь, что все пакеты с объявлениями, от которых зависит ваш пакет, указаны в файле `package.json` в секции `"dependencies"`. 34 | Например, представим, что мы создали пакет, который использует Browserify и TypeScript. 35 | 36 | ```json 37 | { 38 | "name": "browserify-typescript-extension", 39 | "author": "Vandelay Industries", 40 | "version": "1.0.0", 41 | "main": "./lib/main.js", 42 | "types": "./lib/main.d.ts", 43 | "dependencies": [ 44 | "browserify@latest", 45 | "@types/browserify@latest", 46 | "typescript@next" 47 | ] 48 | } 49 | ``` 50 | 51 | Здесь указывается, что наш пакет зависит от пакетов `browserify` и `typescript`. 52 | Пакет `browserify` из npm не поставляется со своими файлами объявлений, поэтому для их добавления нужно указать зависимость от `@types/browserify`. 53 | `typescript`, напротив, поставляется с файлами объявлений, поэтому никаких дополнительных зависимостей не требуется. 54 | 55 | Наш пакет представляет доступ к объявлениям из обоих этих пакетов, и поэтому у пользователя нашего пакета `browserify-typescript-extension` также должны быть установлены эти зависимости. 56 | Поэтому используется `"dependencies"`, а не `"devDependencies"`, поскольку во втором случае нашим пользователям пришлось бы устанавливать зависимости вручную. 57 | Если бы мы писали приложение, работающее из командной строки, и этот пакет не предполагалось бы использовать как библиотеку, то можно было бы использовать `devDependencies`. 58 | 59 | ## Опасные места 60 | 61 | ### `/// ` 62 | 63 | *Не* используйте `/// ` в файлах объявлений. 64 | 65 | ```ts 66 | /// 67 | .... 68 | ``` 69 | 70 | Вместо этого *используйте* `/// `. 71 | 72 | ```ts 73 | /// 74 | .... 75 | ``` 76 | 77 | Обязательно еще раз прочтите [Использование зависимостей](./Library Structures.html#Использование-зависимостей) для большей информации. 78 | 79 | ### Упаковка зависимых объявлений 80 | 81 | Если объявления типов зависят от других пакетов: 82 | 83 | * *Не объединяйте* их со своими, храните каждый в своем файле. 84 | * *Не копируйте* объявления в свой пакет. 85 | * *Добавьте зависимость* от npm-пакета с объявлениями для нужного пакета, если они не поставляются вместе с ним. 86 | 87 | ## Публикация файлов объявлений 88 | 89 | После публикации своего пакета с файлами объявлений добавьте ссылку на него в [список внешних пакетов репозитория DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/types-2.0/notNeededPackages.json). 90 | Это даст инструментам поиска понять, что ваш пакет предоставляет свои собственные объявления. 91 | 92 | # Публикация в [@types](https://www.npmjs.com/~types) 93 | 94 | Пакеты организации [@types](https://www.npmjs.com/~types) автоматически публикуются из репозитория [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped) с помощью [инструмента types-publisher](https://github.com/Microsoft/types-publisher). 95 | Чтобы опубликовать свои объявления как пакет в организации @types, отправьте запрос на включение изменений (pull request) в репозиторий [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped). 96 | Больше информации можно найти на странице [руководства по участию](http://definitelytyped.org/guides/contributing.html). 97 | 98 | [Источник](http://typescript-lang.ru/docs/declaration%20files/Publishing.html) -------------------------------------------------------------------------------- /pages/Triple-Slash Directives.md: -------------------------------------------------------------------------------- 1 | Директивы с тремя наклонными чертами (triple-slash directives) являются однострочными комментариями, включающими в себя единственный тэг XML. 2 | Содержимое комментария используется в качестве директив компилятору. 3 | 4 | Директивы с тремя наклонными чертами имеют силу, находясь **только** в начале содержащего их файла. 5 | Перед директивой с тремя наклонными чертами могут идти только однострочные или многострочные комментарии, а также другие директивы с тремя наклонными чертами. 6 | Если такая директива встретится после команды или объявления, она будет считаться однострочным комментарием, не имеющим специального значения. 7 | 8 | ## `/// ` 9 | 10 | Директива `/// ` используется наиболее часто. 11 | Она служит в качестве объявления *зависимости* между файлами. 12 | 13 | Ссылки с тремя наклонными чертами говорят компилятору о необходимости включения дополнительных файлов в процесс компиляции. 14 | 15 | Они также служат для упорядочивания вывода при использовании `--out` или `--outFile`. 16 | Файлы создаются в выходном каталоге в том же порядке, в каком были поданы на вход после прохода предварительный обработки. 17 | 18 | ### Предварительная обработка входных файлов 19 | 20 | Чтобы разрешить директивы с тремя наклонными чертами, компилятор выполняет проход для предварительной обработки входных файлов. 21 | Во время этой процедуры в компиляцию добавляются дополнительные файлы. 22 | 23 | Процесс начинается с набора *корневых файлов* (root files) - 24 | это имена файлов, указанные в командной строке или в списке `"files"` файла `tsconfig.json`. 25 | Эти корневые файлы обрабатываются в том же порядке, в каком они были указаны. 26 | До того, как файл добавляется в список, обрабатываются все находящиеся в этом файле ссылки с тремя наклонными чертами. 27 | Ссылки с тремя наклонными чертами разрешаются способом поиска в глубину (depth first manner), в порядке, в каком они были представлены в файле. 28 | 29 | Если в ссылке с тремя наклонными чертами не указан полный путь, она разрешается относительно содержащего её файла. 30 | 31 | ### Ошибки 32 | 33 | Ссылка не несуществующий файл является ошибкой. 34 | Если в файле есть ссылка с тремя наклонными чертами на самого себя, это также будет ошибкой. 35 | 36 | ### Использование `--noResolve` 37 | 38 | Если указан флаг компилятора `--noResolve`, то ссылки с тремя наклонными чертами игнорируются: не будут добавлены какие-либо новые файлы и не будет изменен порядок предоставленных файлов. 39 | 40 | ## `/// ` 41 | 42 | Такая директива помечает файл в качестве *библиотеки по умолчанию*. 43 | Подобный комментарий можно найти в начале файла `lib.d.ts`, а также в его различных вариантах. 44 | 45 | Эта директива говорит компилятору *не* включать в сборку библиотеку по умолчанию (например `lib.d.ts`). 46 | В данном случае результат аналогичен указанию в командной строке ключа `--noLib`. 47 | 48 | Также стоит отметить, что при указании ключа `--skipDefaultLibCheck` компилятор пропустит лишь файлы с `/// `. 49 | 50 | ## `/// ` 51 | 52 | Модули AMD по умолчанию генерируются безымянными. 53 | Это может привести к проблемам в случаях, когда для обработки получившихся модулей используются сторонние инструменты создания пакетов (bundlers) (например `r.js`). 54 | 55 | Директива `amd-module` позволяет передать компилятору необязательное имя модуля: 56 | 57 | ##### amdModule.ts 58 | 59 | ```ts 60 | /// 61 | export class C { 62 | } 63 | ``` 64 | 65 | Приведет к присвоению модулю имени `NamedModule` в составе вызова AMD `define`: 66 | 67 | ##### amdModule.js 68 | 69 | ```js 70 | define("NamedModule", ["require", "exports"], function (require, exports) { 71 | var C = (function () { 72 | function C() { 73 | } 74 | return C; 75 | })(); 76 | exports.C = C; 77 | }); 78 | ``` 79 | 80 | ## `/// ` 81 | 82 | > **Замечание**: данная директива объявлена устаревшей. Вместо нее используйте команду `import "moduleName";`. 83 | 84 | `/// ` сообщает компилятору о зависимости от стороннего модуля, ссылка на который должна быть вставлена в команду require уже после обработки. 85 | 86 | Директива `amd-dependency` также может содержать необязательное свойство `name`, позволяющее передать имя для amd-зависимости: 87 | 88 | ```ts 89 | /// 90 | declare var moduleA:MyType 91 | moduleA.callStuff() 92 | ``` 93 | 94 | Сгенерированный JS-код: 95 | 96 | ```js 97 | define(["require", "exports", "legacy/moduleA"], function (require, exports, moduleA) { 98 | moduleA.callStuff() 99 | }); 100 | ``` 101 | 102 | [Источник](http://typescript-lang.ru/docs/Triple-Slash%20Directives.html) -------------------------------------------------------------------------------- /pages/tsconfig.json.md: -------------------------------------------------------------------------------- 1 | ## Обзор 2 | 3 | Наличие файла `tscofnig.json` в директории означает, что данная директория является корнем TypeScript-проекта. 4 | Файл `tsconfig.json` указывает входные файлы и опции компилятора для сборки проекта. 5 | Проект компилируется одним из следующих способов: 6 | 7 | ## Использование tsconfig.json 8 | 9 | * Вызов `tsc` без указания входных файлов, в случае чего компилятор ищет файл `tsconfig.json`, начиная с текущей директории и поднимаясь вверх по цепочке родительских директорий. 10 | * Вызов `tsc` без указания входных файлов и опцией `--project` (или просто `-p`), которая указывает путь к директории, содержащей файл `tsconfig.json`. 11 | 12 | Когда входные файлы указываются в командной строке, файлы `tsconfig.json` игнорируются. 13 | 14 | ## Примеры 15 | 16 | Примеры файлов `tsconfig.json`: 17 | 18 | * Использование свойства `"files"` 19 | 20 | ```json 21 | { 22 | "compilerOptions": { 23 | "module": "commonjs", 24 | "noImplicitAny": true, 25 | "removeComments": true, 26 | "preserveConstEnums": true, 27 | "outFile": "../../built/local/tsc.js", 28 | "sourceMap": true 29 | }, 30 | "files": [ 31 | "core.ts", 32 | "sys.ts", 33 | "types.ts", 34 | "scanner.ts", 35 | "parser.ts", 36 | "utilities.ts", 37 | "binder.ts", 38 | "checker.ts", 39 | "emitter.ts", 40 | "program.ts", 41 | "commandLineParser.ts", 42 | "tsc.ts", 43 | "diagnosticInformationMap.generated.ts" 44 | ] 45 | } 46 | ``` 47 | 48 | * Использование свойств `"include"` и `"exclude"` 49 | 50 | ```json 51 | { 52 | "compilerOptions": { 53 | "module": "commonjs", 54 | "noImplicitAny": true, 55 | "removeComments": true, 56 | "preserveConstEnums": true, 57 | "outFile": "../../built/local/tsc.js", 58 | "sourceMap": true 59 | }, 60 | "include": [ 61 | "src/**/*" 62 | ], 63 | "exclude": [ 64 | "node_modules", 65 | "**/*.spec.ts" 66 | ] 67 | } 68 | ``` 69 | 70 | ## Подробности 71 | 72 | Свойство `"compilerOptions"` можно пропускать, в этом случае компилятор использует значения по умолчанию. Смотрите полный список [опций компилятора](./Compiler Options.html). 73 | 74 | Свойство `"files"` принимает список относительных или абсолютных путей к файлам. 75 | Свойства `"include"` и `"exclude"` принимают список файловых масок. 76 | Поддерживаемые символы замены в файловых масках: 77 | 78 | * `*` соответствует нулю или более символам (кроме разделителей директорий) 79 | * `?` соответствует одному любому символу (кроме разделителя директорий) 80 | * `**/` рекурсивно соответствует любой поддиректории 81 | 82 | Если сегмент файловой маски содержит только `*` или `.*`, то включены будут только файлы с поддерживаемыми расширениями (т. е., `.ts`, `.tsx` или `.d.ts` по умолчанию, и `.js` и `.jsx` если `allowJs` установлено в `true`). 83 | 84 | Если и `"files"` и `"includes"` не указаны, компилятор включает все файлы TypeScript (`.ts`, `.d.ts` и `.tsx`) в содержащей директории и ее поддиректориях кроме тех, которые исключены с помощью свойства `"exclude"`. Также включаются JS-файлы (`.js` и `.jsx`), если `allowJs` установлено в `true`. 85 | Если указаны свойства `"files"` или `"include"`, компилятор вместо этого включит объединение файлов, указанных в этих двух свойствах. 86 | Файлы в директории, указанной посредством опции компилятора `"outDir"` всегда исключаются, если только явно не включены через свойство `"files"` (даже если указано свойство `exclude`). 87 | 88 | Файлы, включенные с помощью `"include"` могут быть отфильтрованы с помощью свойства `"exclude"`. 89 | Тем не менее, файлы, явно включенные через свойство `"files"` включаются всегда, несмотря на `"exclude"`. 90 | Свойство `"exclude"`, если не указано, по умолчанию исключает директории `node_modules`, `bower_components`, и `jspm_packages`. 91 | 92 | Любые файлы, на которые ссылаются файлы, включенные через `"files"` или `"include"`, также включаются. 93 | Аналогично, если файл `A.ts` ссылается на `B.ts`, то `B.ts` не может быть исключен, если только ссылающийся на него файл `A.ts` также не будет указан в списке `"exclude"`. 94 | 95 | Файл `tsconfig.json` может быть совершенно пуст, в таком случае компилируются все файлы, включаемые по умолчанию (как указано выше) с опциями компилятора по умолчанию. 96 | 97 | Опции компилятора, указываемые через командную строку, перезаписывают опции, указанные в файле `tsconfig.json`. 98 | 99 | ## `compileOnSave` 100 | 101 | Указание на верхнем уровне свойства `compileOnSave` указывает IDE генерировать все файлы для данного `tsconfig.json` при сохранении. 102 | 103 | ```json 104 | { 105 | "compileOnSave": true, 106 | "compilerOptions": { 107 | "noImplicitAny" : true 108 | } 109 | } 110 | ``` 111 | 112 | Эта возможность на данный момент поддерживается в Visual Studio 2015 с TypeScript 1.8.4 и выше и дополнением [atom-typescript](https://github.com/TypeStrong/atom-typescript/blob/master/docs/tsconfig.html#compileonsave). 113 | 114 | ## Структура 115 | 116 | Описание структуры находится по адресу: [http://json.schemastore.org/tsconfig](http://json.schemastore.org/tsconfig) 117 | 118 | [Источник](http://typescript-lang.ru/docs/tsconfig.json.html) -------------------------------------------------------------------------------- /pages/Integrating with Build Tools.md: -------------------------------------------------------------------------------- 1 | # Browserify 2 | 3 | ### Установка 4 | 5 | ```sh 6 | npm install tsify 7 | ``` 8 | 9 | ### Использование интерфейса командной строки 10 | 11 | ```sh 12 | browserify main.ts -p [ tsify --noImplicitAny ] > bundle.js 13 | ``` 14 | 15 | ### Использование API 16 | 17 | ```js 18 | var browserify = require("browserify"); 19 | var tsify = require("tsify"); 20 | 21 | browserify() 22 | .add("main.ts") 23 | .plugin("tsify", { noImplicitAny: true }) 24 | .bundle() 25 | .pipe(process.stdout); 26 | ``` 27 | 28 | Больше информации: [smrq/tsify](https://github.com/smrq/tsify) 29 | 30 | # Duo 31 | 32 | ### Установка 33 | 34 | ```sh 35 | npm install duo-typescript 36 | ``` 37 | 38 | ### Использование интерфейса командной строки 39 | 40 | ```sh 41 | duo --use duo-typescript entry.ts 42 | ``` 43 | 44 | ### Использование API 45 | 46 | ```js 47 | var Duo = require("duo"); 48 | var fs = require("fs") 49 | var path = require("path") 50 | var typescript = require("duo-typescript"); 51 | 52 | var out = path.join(__dirname, "output.js") 53 | 54 | Duo(__dirname) 55 | .entry("entry.ts") 56 | .use(typescript()) 57 | .run(function (err, results) { 58 | if (err) throw err; 59 | // Записать результат компиляции в файл 60 | fs.writeFileSync(out, results.code); 61 | }); 62 | ``` 63 | 64 | Больше информации: [frankwallis/duo-typescript](https://github.com/frankwallis/duo-typescript) 65 | 66 | # Grunt 67 | 68 | ### Установка 69 | 70 | ```sh 71 | npm install grunt-ts 72 | ``` 73 | 74 | ### Базовый Gruntfile.js 75 | 76 | ````js 77 | module.exports = function(grunt) { 78 | grunt.initConfig({ 79 | ts: { 80 | default : { 81 | src: ["**/*.ts", "!node_modules/**/*.ts"] 82 | } 83 | } 84 | }); 85 | grunt.loadNpmTasks("grunt-ts"); 86 | grunt.registerTask("default", ["ts"]); 87 | }; 88 | ```` 89 | Больше информации: [TypeStrong/grunt-ts](https://github.com/TypeStrong/grunt-ts) 90 | 91 | # gulp 92 | 93 | ### Установка 94 | 95 | ```sh 96 | npm install gulp-typescript 97 | ``` 98 | 99 | ### Базовый gulpfile.js 100 | 101 | ```js 102 | var gulp = require("gulp"); 103 | var ts = require("gulp-typescript"); 104 | 105 | gulp.task("default", function () { 106 | var tsResult = gulp.src("src/*.ts") 107 | .pipe(ts({ 108 | noImplicitAny: true, 109 | out: "output.js" 110 | })); 111 | return tsResult.js.pipe(gulp.dest("built/local")); 112 | }); 113 | ``` 114 | 115 | Больше информации: [ivogabe/gulp-typescript](https://github.com/ivogabe/gulp-typescript) 116 | 117 | # jspm 118 | 119 | ### Установка 120 | 121 | ```sh 122 | npm install -g jspm@beta 123 | ``` 124 | 125 | _Замечание: На данный момент поддержка TypeScript в jspm есть в версии 0.16beta_ 126 | 127 | Больше информации: [TypeScriptSamples/jspm](https://github.com/Microsoft/TypeScriptSamples/tree/master/jspm) 128 | 129 | # webpack 130 | 131 | ### Установка 132 | 133 | ```sh 134 | npm install ts-loader --save-dev 135 | ``` 136 | 137 | ### Базовый webpack.config.js 138 | 139 | ```js 140 | module.exports = { 141 | entry: "./src/index.tsx", 142 | output: { 143 | filename: "bundle.js" 144 | }, 145 | resolve: { 146 | // Добавить расширения '.ts' и '.tsx' в список разрешаемых 147 | extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"] 148 | }, 149 | module: { 150 | loaders: [ 151 | // все файлы с расширениями 'ts' или '.tsx' будет обрабатывать `ts-loader' 152 | { test: /\.tsx?$/, loader: "ts-loader" } 153 | ] 154 | } 155 | } 156 | ``` 157 | 158 | См. [больше информации о ts-loader](https://www.npmjs.com/package/ts-loader). 159 | 160 | Альтернативы: 161 | 162 | * [awesome-typescript-loader](https://www.npmjs.com/package/awesome-typescript-loader) 163 | 164 | # MSBuild 165 | 166 | Обновите файл файл проекта, включив установленные локально файлы `Microsoft.TypeScript.Default.props` (в начале файла) и `Microsoft.TypeScript.targets` (в конце файла). 167 | 168 | ```xml 169 | 170 | 171 | 172 | 175 | 176 | 177 | 178 | false 179 | true 180 | 181 | 182 | true 183 | false 184 | 185 | 186 | 187 | 190 | 191 | ``` 192 | 193 | Больше информации об указании опций компилятора MSBuild: [Установка опций компилятора в проектах MSBuild](./Compiler Options in MSBuild.md) 194 | 195 | # NuGet 196 | 197 | * Щелкнуть правой кнопкой -> Управление пакетами NuGet (`Manage NuGet Packages`) 198 | * Найти `Microsoft.TypeScript.MSBuild` 199 | * Нажать `Установить` (`Install`) 200 | * Когда установка закончится, пересобрать проект! 201 | 202 | Больше информации: [Управление пакетами](http://docs.nuget.org/Consume/Package-Manager-Dialog) и [Использование ночных сборок с NuGet](https://github.com/Microsoft/TypeScript/wiki/Nightly-drops#using-nuget-with-msbuild) 203 | 204 | [Источник](http://typescript-lang.ru/docs/Integrating%20with%20Build%20Tools.html) -------------------------------------------------------------------------------- /pages/Namespaces and Modules.md: -------------------------------------------------------------------------------- 1 | > **Замечание по поводу терминологии:** 2 | Важно отметить, что в TypeScript 1.5 изменилась номенклатура. 3 | "Внутренние модули" теперь называются "пространства имён". 4 | "Внешние модули" стали просто "модулями". Это было сделано, чтобы согласовать терминологию с [ECMAScript 2015](http://www.ecma-international.org/ecma-262/6.0/), (а именно: `module X {` эквивалентен предпочитаемому в настоящее время `namespace X {`). 5 | 6 | # Введение 7 | 8 | Данный раздел документации описывает различные пути организации вашего кода в TypeScript с помощью пространств имён и модулей. 9 | Мы также затронем несколько сложных вопросов и отметим основные подводные камни, которые могут встретиться при использовании пространств имен и модулей в Typescript. 10 | 11 | См. [модули](./Modules.html) для получения более подробной информации о модулях. 12 | См. [пространства имен](./Namespaces.html) для получения более подробной информации о пространствах имен. 13 | 14 | # Использование пространств имен 15 | 16 | Пространства имен — это просто именованные объекты JavaScript, расположенные в глобальном пространстве имен. И это делает их очень простыми в использовании. 17 | Пространства имен могут располагаться в нескольких файлах и могут быть объединены с помощью ключа `--outFile`. 18 | Они удобны для структурирования кода в веб-приложении, когда все зависимости находятся в тегах ` 160 | 161 | 164 | 165 | 166 | ``` 167 | 168 | Обратите внимание, что здесь три тега `script`. 169 | Сначала мы включаем саму библиотеку RequireJS. 170 | Затем мы задаем соответствие путям внешних зависимостей в файле `require-config.js`, чтобы RequireJS знала, где искать зависимости. 171 | И, наконец, мы вызываем `require` со списком загружаемых модулей. 172 | 173 | # Собираем все вместе 174 | 175 | Просто запустите: 176 | 177 | ```shell 178 | tsc 179 | ``` 180 | 181 | Теперь откройте `index.html` в любимом браузере, и все должно быть готово! 182 | Вы должны увидеть страницу с текстом "Привет от TypeScript и Knockout!". 183 | Ниже будут два поля ввода. 184 | При изменении их содержимого и переводе фокуса исходное сообщение будет изменяться. 185 | 186 | [Источник](http://typescript-lang.ru/docs/tutorials/Knockout.html) -------------------------------------------------------------------------------- /pages/declaration files/Do's and Don'ts.md: -------------------------------------------------------------------------------- 1 | # Основные типы 2 | 3 | ## `Number`, `String`, `Boolean`, и `Object` 4 | 5 | Никогда *не используйте* типы `Number`, `String`, `Boolean` или `Object`. 6 | Эти типы ссылаются на непримитивные упакованные типы, которые почти никогда не используются в JavaScript-коде. 7 | 8 | ```ts 9 | /* НЕПРАВИЛЬНО */ 10 | function reverse(s: String): String; 11 | ``` 12 | 13 | *Используйте* типы `number`, `string` и `boolean`. 14 | 15 | ```ts 16 | /* ПРАВИЛЬНО */ 17 | function reverse(s: string): string; 18 | ``` 19 | 20 | Если вам хочется применить тип `Object`, используйте вместо него `any`. 21 | На данный момент в TypeScript нет способа указать, что объект должен быть "непримитивным". 22 | 23 | ## Обобщения 24 | 25 | Никогда *не создавайте* обобщенный тип, который не использует типовый параметр. 26 | Больше информации на странице [часто задаваемых вопросов](https://github.com/Microsoft/TypeScript/wiki/FAQ#why-doesnt-type-inference-work-on-this-interface-interface-foot---). 27 | 28 | # Типы функций обратного вызова 29 | 30 | ## Типы возвращаемых значений функций обратного вызова 31 | 32 | *Не используйте* `any` в качестве типа возвращаемого значения для функций обратного вызова, чье возвращаемое значение игнорируется: 33 | 34 | ```ts 35 | /* НЕПРАВИЛЬНО */ 36 | function fn(x: () => any) { 37 | x(); 38 | } 39 | ``` 40 | 41 | *Используйте* тип `void` в подобных случаях: 42 | 43 | ```ts 44 | /* ПРАВИЛЬНО */ 45 | function fn(x: () => void) { 46 | x(); 47 | } 48 | ``` 49 | 50 | *Почему*: использование `void` более безопасно, поскольку защищает от случайного использования возвращаемого значения `x` без проверки типов: 51 | 52 | ```ts 53 | function fn(x: () => void) { 54 | var k = x(); // упс! планировалось написать что-то другое 55 | k.doSomething(); // ошибка, но все было бы нормально, если бы тип возвращаемого значения был 'any' 56 | } 57 | ``` 58 | 59 | ## Необязательные параметры в функциях обратного вызова 60 | 61 | *Не используйте* необязательные параметры в функциях обратного вызова, кроме случаев, когда они необходимы: 62 | 63 | ```ts 64 | /* НЕПРАВИЛЬНО */ 65 | interface Fetcher { 66 | getObject(done: (data: any, elapsedTime?: number) => void): void; 67 | } 68 | ``` 69 | 70 | Это имеет следующее значение: функция обратного вызова `done` может быть вызвана либо с одним, либо с двумя аргументами. 71 | Разработчик, вероятно, намеревался выразить то, что функция обратного вызова может не обращать внимания на параметр `elapsedTime`, однако для этого не нужно делать параметр необязательным -- передача функции обратного вызова, которая принимает меньшее число аргументов, всегда допускается. 72 | 73 | Всегда *используйте* обязательные параметры для функции обратного вызова: 74 | 75 | ```ts 76 | /* ПРАВИЛЬНО */ 77 | interface Fetcher { 78 | getObject(done: (data: any, elapsedTime: number) => void): void; 79 | } 80 | ``` 81 | 82 | ## Перегрузки и функции обратного вызова 83 | 84 | *Не создавайте* отдельных перегрузок, различающихся только числом аргументов у функции обратного вызова: 85 | 86 | ```ts 87 | /* НЕПРАВИЛЬНО */ 88 | declare function beforeAll(action: () => void, timeout?: number): void; 89 | declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void; 90 | ``` 91 | 92 | *Создавайте* одну общую перегрузку с максимальным числом аргументов: 93 | 94 | ```ts 95 | /* ПРАВИЛЬНО */ 96 | declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void; 97 | ``` 98 | 99 | *Почему*: функция с меньшим числом параметров всегда допустима, поэтому необходимости в более короткой перегрузке нет. 100 | Добавление в начало варианта с более короткой перегрузкой приводит к тому, что неподходящие по типу функции будут допускаться, поскольку подходят к первой перегрузке. 101 | 102 | # Перегрузки функций 103 | 104 | ## Упорядочивание 105 | 106 | *Не помещайте* более общие перегрузки перед более специфичными: 107 | 108 | ```ts 109 | /* НЕПРАВИЛЬНО */ 110 | declare function fn(x: any): any; 111 | declare function fn(x: HTMLElement): number; 112 | declare function fn(x: HTMLDivElement): string; 113 | 114 | var myElem: HTMLDivElement; 115 | var x = fn(myElem); // x: any, wat? 116 | ``` 117 | 118 | *Сортируйте* перегрузки так, чтобы более общие находились после более специфичных: 119 | 120 | ```ts 121 | /* ПРАВИЛЬНО */ 122 | declare function fn(x: HTMLDivElement): string; 123 | declare function fn(x: HTMLElement): number; 124 | declare function fn(x: any): any; 125 | 126 | var myElem: HTMLDivElement; 127 | var x = fn(myElem); // x: string, :) 128 | ``` 129 | 130 | *Почему*: при разрешении вызовов функции TypeScript выбирает *первую подходящую перегрузку*. 131 | Если первая перегрузка является более общей, чем последующие, то последующие перегрузки оказываются скрыты и не могут быть вызваны. 132 | 133 | ## Используйте необязательные параметры 134 | 135 | *Не создавайте* несколько перегрузок, отличающихся только конечными аргументами: 136 | 137 | ```ts 138 | /* НЕПРАВИЛЬНО */ 139 | interface Moment { 140 | diff(b: MomentComparable): number; 141 | diff(b: MomentComparable, unitOfTime: string): number; 142 | diff(b: MomentComparable, unitOfTime: string, round: boolean): number; 143 | } 144 | ``` 145 | 146 | *Используйте* необязательные параметры, если это возможно: 147 | 148 | ```ts 149 | /* ПРАВИЛЬНО */ 150 | interface Moment { 151 | diff(b: MomentComparable, unitOfTime?: string, round?: boolean): number; 152 | } 153 | ``` 154 | 155 | Обратите внимание, что подобное "схлопывание" возможно только если у всех перегрузок один и тот же тип возвращаемого значения. 156 | 157 | *Почему*: Это важно по двум причинам. 158 | 159 | TypeScript определяет совместимость сигнатур, определяя, может ли какая-либо сигнатура цели вызвана с аргументами исходной сигнатуры, причем *лишние аргументы допускаются*. 160 | Следующий код, например, позволяет обнаружить ошибку только в том случае, если сигнатура правильно записана с использованием необязательных параметров: 161 | 162 | ```ts 163 | function fn(x: (a: string, b: number, c: number) => void) { } 164 | var x: Moment; 165 | // Если записано с перегрузками, все нормально -- использована первая перегрузка 166 | // Если записано с необязательными параметрами, обнаруживается ошибка 167 | fn(x.diff); 168 | ``` 169 | 170 | Вторая причина -- применение к коду, использующему библиотеку, "строгой проверки на `null`". 171 | Поскольку пропущенные параметры для JavaScript выглядят как `undefined`, то, как правило, функции с необязательными параметрами можно явно передать `undefined`. 172 | Следующий код, например, должен компилироваться при строгой проверке на `null`: 173 | 174 | ```ts 175 | var x: Moment; 176 | // Если записано с перегрузками, то несправедливая ошибка, так как передается 'undefined' вместо 'string' 177 | // Если записано с необязательными параметрами, то все нормально 178 | x.diff(something, someOtherThing ? undefined : "hour"); 179 | ``` 180 | 181 | ## Используйте объединения 182 | 183 | *Не создавайте* перегрузок, которые отличаются только типом одного аргумента: 184 | 185 | ```ts 186 | /* НЕПРАВИЛЬНО */ 187 | interface Moment { 188 | utcOffset(): number; 189 | utcOffset(b: number): Moment; 190 | utcOffset(b: string): Moment; 191 | } 192 | ``` 193 | 194 | *Используйте* объединения, если это возможно: 195 | 196 | ```ts 197 | /* ПРАВИЛЬНО */ 198 | interface Moment { 199 | utcOffset(): number; 200 | utcOffset(b: number|string): Moment; 201 | } 202 | ``` 203 | 204 | Обратите внимание, что параметр `b` не сделан необязательным, так как типы возвращаемых значений различаются. 205 | 206 | *Почему*: Это важно для тех, кто передает значения "сквозь" функцию: 207 | 208 | ```ts 209 | function fn(x: string): void; 210 | function fn(x: number): void; 211 | function fn(x: number|string) { 212 | // Если записано с отдельными перегрузками, то несправедливая ошибка 213 | // Если записано с объединениями, то все нормально 214 | return moment().utcOffset(x); 215 | } 216 | ``` 217 | 218 | [Источник](http://typescript-lang.ru/docs/declaration%20files/Do's%20and%20Don'ts.html) -------------------------------------------------------------------------------- /pages/declaration files/Deep Dive.md: -------------------------------------------------------------------------------- 1 | # Теоретические основы файлов определений: глубокое погружение 2 | 3 | Описать модуль так, чтобы он имел в точности необходимый API, может оказаться сложной задачей. 4 | К примеру, может понадобиться модуль, который вызывается с `new` или без, создавая при этом разные типы, имеет различные именованные типы, упорядоченные иерархически, и несколько свойств на самом объекте модуля. 5 | 6 | Прочитав это руководство, вы получите инструменты для написания сложных файлов определений, предоставляющих удобный API. 7 | Это руководство уделяет основное внимание модульным (или UMD) библиотекам из-за множества их вариантов и разнообразия. 8 | 9 | ## Ключевые принципы 10 | 11 | Для того, чтобы понять, как придать определению любую форму, нужно понять ключевые принципы работы TypeScript. 12 | 13 | ### Типы 14 | 15 | Если вы читаете это руководство, то, наверное, уже примерно представляете, что такое тип в TypeScript. 16 | Но для большей ясности укажем, что тип вводится с помощью: 17 | 18 | * Объявления псевдонима типа (`type sn = number | string;`) 19 | * Объявления интерфейса (`interface I { x: number[]; }`) 20 | * Объявления класса (`class C { }`) 21 | * Объявления перечисления (`enum E { A, B, C }`) 22 | * Объявления `import`, которое ссылается на тип 23 | 24 | Каждое из таких объявлений создает новое имя типа. 25 | 26 | ### Значения 27 | 28 | Как и с типами, вы, скорее всего, понимаете, что такое значения. 29 | Значения — это имена, на которые можно ссылаться в выражениях во время выполнения кода. 30 | К примеру, `let x = 5;` создает значение под именем `x`. 31 | 32 | Опять же, для ясности, укажем, что значения создаются следующими конструкциями: 33 | 34 | * объявлениями `let`, `const` и `var`. 35 | * объявлениями `namespace` или `module`, внутри которых содержится значение 36 | * объявлением `enum` 37 | * объявлением `class` 38 | * объявлением `import`, которое ссылается на значение 39 | * объявлением `function` 40 | 41 | ### Пространства имен 42 | 43 | Типы могут существовать внутри *пространств имен*. 44 | К примеру, если взять объявление `let x: A.B.C`, то можно сказать, что тип `C` находится в пространстве имен `A.B`. 45 | 46 | Здесь есть тонкий и важный момент — `A.B` не обязательно является типом или значением. 47 | 48 | ## Простые сочетания: одно имя, несколько значений 49 | 50 | Взяв имя `A`, можно прийти к одному из трех вариантов того, что оно означает: тип, значение или пространство имен. 51 | Как интерпретируется имя, зависит от контекста, в котором оно используется. 52 | К примеру, в объявлении `let m: A.A = A;` имя `A` в первый раз используется как пространство имен, потом как имя типа, а затем как значение. 53 | Разные варианты могут приводить к указанию на совершенно разные объявления! 54 | 55 | Все это может показаться запутанным, но на самом деле очень удобно, если только имена не слишком перегружаются. 56 | Посмотрим на полезные стороны такого поведения сочетаний. 57 | 58 | ### Встроенные сочетания 59 | 60 | Проницательный читатель мог заметить, что, например, `class` появляется и в списке *типов*, и в списке *значений*. 61 | Определение `class C { }` создает две вещи: *тип* `C`, который ссылается на форму экземпляра класса, и *значение* `C`, которое ссылается на функцию-конструктор для данного класса. 62 | Определения перечислений ведут себя так же. 63 | 64 | ### Пользовательские сочетания 65 | 66 | Допустим, мы написали файл модуля `foo.d.ts`: 67 | 68 | ```ts 69 | export var SomeVar: { a: SomeType }; 70 | export interface SomeType { 71 | count: number; 72 | } 73 | ``` 74 | 75 | И затем используем его: 76 | 77 | ```ts 78 | import * as foo from './foo'; 79 | let x: foo.SomeType = foo.SomeVar.a; 80 | console.log(x.count); 81 | ``` 82 | 83 | Это отлично работает, но мы могли бы понять, что `SomeType` и `SomeVar` тесно связаны друг с другом, и захотели бы дать им одно и то же имя. 84 | С помощью сочетания можно представить две различных сущности (значение и тип) под одним именем `Bar`: 85 | 86 | ```ts 87 | export var Bar: { a: Bar }; 88 | export interface Bar { 89 | count: number; 90 | } 91 | ``` 92 | 93 | Это дает хорошую возможность для деструктуризации в использующем модуль коде: 94 | 95 | ```ts 96 | import { Bar } from './foo'; 97 | let x: Bar = Bar.a; 98 | console.log(x.count); 99 | ``` 100 | 101 | Здесь мы использовали `Bar` и как тип, и как значение. 102 | Отметим, что не обязательно определять значение `Bar` как имеющее тип `Bar` — они независимы. 103 | 104 | ## Сложные сочетания 105 | 106 | Некоторые объявления могут сочетаться между несколькими объявлениями. 107 | Например, `class C { }` и `interface C { }` могут сосуществовать, и оба добавлять свойства к типам `C`. 108 | 109 | Это допустимо, пока не создает конфликтов. 110 | Правило таково, что значения всегда конфликтуют с другими значениями с тем же именем, если только они не объявлены как `namespace`; типы конфликтуют, если объявлены с помощью псевдонима типа (`type s = string`), а пространства имен не конфликтуют никогда. 111 | 112 | Посмотрим, как это можно использовать. 113 | 114 | ### Добавление с помощью `interface` 115 | 116 | К интерфейсу можно добавить члены с помощью другого объявления `interface`: 117 | 118 | ```ts 119 | interface Foo { 120 | x: number; 121 | } 122 | // ... где-то в другом месте ... 123 | interface Foo { 124 | y: number; 125 | } 126 | let a: Foo = ...; 127 | console.log(a.x + a.y); // OK 128 | ``` 129 | 130 | Это работает и с классами: 131 | 132 | ```ts 133 | class Foo { 134 | x: number; 135 | } 136 | // ... где-то в другом месте ... 137 | interface Foo { 138 | y: number; 139 | } 140 | let a: Foo = ...; 141 | console.log(a.x + a.y); // OK 142 | ``` 143 | 144 | Отметим, что с помощью интерфейса нельзя добавить что-либо к псевдониму типа (`type s = string;`). 145 | 146 | ### Добавление с помощью `namespace` 147 | 148 | Объявление `namespace` можно использовать для добавления новых типов, значений и пространств имен, если это не создает конфликтов. 149 | 150 | К примеру, можно добавить статический член к классу: 151 | 152 | ```ts 153 | class C { 154 | } 155 | // ... где-то в другом месте ... 156 | namespace C { 157 | export let x: number; 158 | } 159 | let y = C.x; // OK 160 | ``` 161 | 162 | В данном примере значение было добавлено к *статической* части `C` (функции-конструктору). 163 | Так произошло потому, что мы добавили *значение*, а контейнером для значения может служить только другое значение (типы содержатся в пространствах имен, а пространства имен — в других пространствах имен). 164 | 165 | Тем же способом к классу можно добавить тип: 166 | 167 | ```ts 168 | class C { 169 | } 170 | // ... где-то в другом месте ... 171 | namespace C { 172 | export interface D { } 173 | } 174 | let y: C.D; // OK 175 | ``` 176 | 177 | В этом примере пространства имен `C` не существовало, пока мы не написали объявление `namespace` для него. 178 | `C` в смысле пространства имен не конфликтует со значениями или типами под именем `C`, которые создаются объявлением класса. 179 | 180 | И наконец, с помощью объявлений `namespace` можно осуществлять различные виды слияний. 181 | Следующий пример не очень реалистичен, но показывает все разновидности интересного поведения: 182 | 183 | ```ts 184 | namespace X { 185 | export interface Y { } 186 | export class Z { } 187 | } 188 | 189 | // ... где-то в другом месте ... 190 | namespace X { 191 | export var Y: number; 192 | export namespace Z { 193 | export class C { } 194 | } 195 | } 196 | type X = string; 197 | ``` 198 | 199 | В этом примере первый блок создает следующие смыслы для имен: 200 | 201 | * Значение `X` (поскольку объявление пространства имен содержит значение, `Z`) 202 | * Пространство имен `X` (поскольку объявление пространства имен содержит тип, `Y`) 203 | * Тип `Y` в пространстве имен `X` 204 | * Тип `Z` в пространстве имен `X` (часть экземпляра класса) 205 | * Значение `Z`, которое является свойством значения `X` (функция-конструктор класса) 206 | 207 | Второй блок создает следующие смыслы: 208 | 209 | * Значение `Y` (с типом `number`), которое является свойством значения `X` 210 | * Пространство имен `Z` 211 | * Значение `Z`, которое является свойством значения `X` 212 | * Тип `C` внутри пространства имен `X.Z` 213 | * Значение `C`, которое является свойством значения `X.Z` 214 | * Тип `X` 215 | 216 | ## Использование с `export = ` или `import` 217 | 218 | Важно, что объявления `export` и `import` экспортируют или импортируют *все смыслы* того, на что ссылаются. 219 | 220 | 221 | [Источник](http://typescript-lang.ru/docs/declaration%20files/Deep%20Dive.html) -------------------------------------------------------------------------------- /pages/Basic Types.md: -------------------------------------------------------------------------------- 1 | # Введение 2 | 3 | Typescript является языком со статической типизацией. Тип не может быть изменен в ходе выполнения программы. Это позволяет снизить большое количество ошибок и выявить многие из них еще на этапе компиляции. 4 | 5 | В Typescript есть несколько простых типов данных: numbers (числа), strings (строки), structures (структуры), boolean (логический). Он поддерживает все типы, которые есть в Javascript, дополняя удобным типом перечислений (enum). 6 | 7 | 8 | # Boolean 9 | 10 | Наиболее базовым типом является логический true/false, который в Javascript и Typescript называется boolean. 11 | 12 | ```ts 13 | let isDone: boolean = false; 14 | ``` 15 | 16 | # Number 17 | 18 | Как и в Javascript, тип numbers в Typescript являются числом с плавающей точкой. Кроме десятичного и шестнадцатиричного формата, поддерживаются бинарный и восьмеричный, введенные в ECMAScript 2015. 19 | 20 | ```ts 21 | let decimal: number = 6; 22 | let hex: number = 0xf00d; 23 | let binary: number = 0b1010; 24 | let octal: number = 0o744; 25 | ``` 26 | 27 | # String 28 | 29 | Еще одна важная часть программ в веб-страницах и серверах это текстовые данные. Как и в других языках, в Typescript используется то же обозначение "string" для таких данных. Как и Javascript, в Typescript используются двойные (`"`) или одинарные (`'`) кавычки для обрамления текстовых данных. 30 | 31 | ```ts 32 | let name: string = "bob"; 33 | name = 'smith'; 34 | ``` 35 | 36 | Вы также можете использовать *строки с шаблонами*, которые могут быть многострочными и иметь встроенные выражения. Эти строки окружаются обратными апострофами или кавычками(`` ` ``) и встроенные выражения обозначаются как `${ expr }`. 37 | 38 | ```ts 39 | let name: string = `Gene`; 40 | let age: number = 37; 41 | let sentence: string = `Hello, my name is ${ name }. 42 | 43 | I'll be ${ age + 1 } years old next month.` 44 | ``` 45 | Эквивалент этого объявления `sentence`: 46 | 47 | ```ts 48 | let sentence: string = "Hello, my name is " + name + ".\n\n" + 49 | "I'll be " + (age + 1) + " years old next month." 50 | ``` 51 | 52 | # Array 53 | 54 | TypeScript, как и JavaScript, имеет массивы значений. 55 | Тип массива может быть определен одним из двух способов. 56 | Первый - обозначать тип элементов массива перед `[]`: 57 | 58 | ```ts 59 | let list: number[] = [1, 2, 3]; 60 | ``` 61 | 62 | Второй способ - использовать обобщение `Array`: 63 | 64 | ```ts 65 | let list: Array = [1, 2, 3]; 66 | ``` 67 | 68 | # Tuple 69 | 70 | Тип Tuple дает вам возможность объявить массив с известным фиксированным количеством элементов, которые не обязаны быть одного типа. Например, вы хотите иметь значение Tuple как пару "строка" и "число": 71 | 72 | ```ts 73 | // Объявление типа tuple 74 | let x: [string, number]; 75 | // Его инициализация 76 | x = ['hello', 10]; // OK 77 | // Некорректная инициализация вызовет ошибку 78 | x = [10, 'hello']; // Error 79 | ``` 80 | 81 | Когда вы получаете элемент с известным идексом, будет возвращен тип этого элемента: 82 | 83 | ```ts 84 | console.log(x[0].substr(1)); // OK 85 | console.log(x[1].substr(1)); // Error, 'number' does not have 'substr' 86 | ``` 87 | 88 | При получении элемента с идексом вне известного диапазона, будет возвращен тип Union: 89 | 90 | ```ts 91 | x[3] = 'world'; // OK, тип string может быть присвоен (string | number) 92 | 93 | console.log(x[5].toString()); // OK, 'string' и 'number' оба имеют метод toString 94 | 95 | x[6] = true; // Ошибка, boolean это не (string | number) 96 | ``` 97 | 98 | Тип Union будет описан чуть позже, в разделе продвинутых типов. 99 | 100 | # Enum (Перечисления) 101 | 102 | Полезным дополнением к стандартному набору типов из Javascript является тип Enum. 103 | Как и в языках подобных C#, тип enum - это более удобный способ задания понятных имен набору численных значений. 104 | 105 | ```ts 106 | enum Color {Red, Green, Blue}; 107 | let c: Color = Color.Green; 108 | ``` 109 | 110 | По умолчанию перечисления (Enum) начинаются с `0`. 111 | Вы можете изменить это путем прямого указания значения для одного из членов перечисления. 112 | Например, мы можем начать предыдущий пример с `1` вместо `0`: 113 | 114 | ```ts 115 | enum Color {Red = 1, Green, Blue}; 116 | let c: Color = Color.Green; 117 | ``` 118 | 119 | Или даже задать значения для всех членов: 120 | 121 | ```ts 122 | enum Color {Red = 1, Green = 2, Blue = 4}; 123 | let c: Color = Color.Green; 124 | ``` 125 | Удобная особенность перечислений состоит в том, что вы также можете получить имя члена перечисления, передав его числовое значение. 126 | Например, если у нас есть значение `2` и мы хотим посмотреть, чему оно соответствует в перечислении `Color` описанном выше, мы можем сделать это так: 127 | 128 | ```ts 129 | enum Color {Red = 1, Green, Blue}; 130 | let colorName: string = Color[2]; 131 | 132 | alert(colorName); 133 | ``` 134 | 135 | # Any 136 | 137 | Нам может потребоваться описать тип переменных, который мы не знаем, когда пишем наше приложение. 138 | Эти значения могут быть получены из динамического контента, например от пользователя или от сторонней библиотеки. 139 | В этих случаях мы хотим отключить проверку типов и позволить значениям пройти проверку на этапе компиляции. 140 | Чтобы это сделать, нужно использовать тип `any`: 141 | 142 | ```ts 143 | let notSure: any = 4; 144 | notSure = "maybe a string instead"; 145 | notSure = false; // ok, это определенно boolean 146 | ``` 147 | Тип `any` - это мощный способ работы с существующим Javascript, который позволяет вам постепенно включать все больше проверок типов на этапе компиляции. 148 | Вы можете ожидать, что `Object` будет играть такую же роль, какую и в других языках. Но переменные типа `Object` позволяют вам только присваивать им любое значение. Вы не можете вызывать у них необъявленные методы, даже те, которые могут существовать на этапе исполнения программы: 149 | 150 | ```ts 151 | let notSure: any = 4; 152 | notSure.ifItExists(); // ifItExists может существовать на этапе исполнения 153 | notSure.toFixed(); // метод toFixed существует (но компилятор не проверяет это) 154 | 155 | let prettySure: Object = 4; 156 | prettySure.toFixed(); // Ошибка: Свойство 'toFixed' не существует у типа 'Object'. 157 | ``` 158 | Тип `any` может быть также полезен, если вы знаете некоторую часть типа переменной, но не весь. 159 | Например, у вас может быть массив с элементами различных типов: 160 | 161 | ```ts 162 | let list: any[] = [1, true, "free"]; 163 | 164 | list[1] = 100; 165 | ``` 166 | 167 | # Void 168 | 169 | `void` это нечто противоположное `any`: отсутствие каких-либо типов. Чаще всего он используется в качестве возвращаемого типа функций, которые не возвращают никакого значения. 170 | 171 | ```ts 172 | function warnUser(): void { 173 | alert("This is my warning message"); 174 | } 175 | ``` 176 | 177 | Объявление переменных с типом `void` бесполезно, потому что вы можете присвоить им только значения `undefined` или `null`: 178 | 179 | ```ts 180 | let unusable: void = undefined; 181 | ``` 182 | 183 | # Type assertions (Приведение к типу) 184 | 185 | Иногда вы попадаете в ситуацию, когда знаете больше о значении переменной, чем Typescript. 186 | Обычно это случается, когда вы знаете, что тип некоторой сущности может быть более специфичным, чем ее текущий. 187 | 188 | *Type assertions* - это способ сказать компилятору "поверь мне, я знаю, что делаю". 189 | Type assertion это как приведение к типу в других языках, но оно не делает никаких специальных проверок или реструктуризаций данных. 190 | Приведение к типу не имеет никакого воздействия на этапе выполнения программы и используется только компилятором. 191 | Typescript предполагает, что программист сделает все необходимые проверки, которые потребуются. 192 | 193 | Приведение к типу может быть сделано двумя способами. 194 | Первый это использование синтаксиса угловых скобок: 195 | 196 | ```ts 197 | let someValue: any = "this is a string"; 198 | 199 | let strLength: number = (someValue).length; 200 | ``` 201 | 202 | И другой - использование ключевого слова `as`: 203 | 204 | ```ts 205 | let someValue: any = "this is a string"; 206 | 207 | let strLength: number = (someValue as string).length; 208 | ``` 209 | 210 | Эти два примера эквивалентны. Использование одного из них это просто выбор более предпочтительного варианта; тем не менее, когда вы используете Typescript с JSX, возможно только приведение к типу через `as`. 211 | 212 | # Немного о `let` 213 | 214 | Вы могли заметить, что недавно было введено новое ключевое слово `let` вместо `var` из JavaScript, с которым вы знакомы. 215 | Ключевое слово `let` - это просто новый способ задания переменной в JavaScript, который уже доступен в Typescript. 216 | Мы обсудим детали позже, сейчас же просто знайте, что много проблем в Javascript можно избежать, используя `let`. Поэтому вы должны использовать его вместо `var`, где это возможно. 217 | 218 | [Источник](http://typescript-lang.ru/docs/Basic%20Types.html) 219 | -------------------------------------------------------------------------------- /pages/Compiler Options in MSBuild.md: -------------------------------------------------------------------------------- 1 | ## Overview 2 | 3 | Compiler options can be specified using MSBuild properties within an MSBuild project. 4 | 5 | ## Example 6 | 7 | ```XML 8 | 9 | false 10 | true 11 | 12 | 13 | true 14 | false 15 | 16 | 19 | ``` 20 | 21 | ## Mappings 22 | 23 | Compiler Option | MSBuild Property Name | Allowed Values 24 | ---------------------------------------------|--------------------------------------------|----------------- 25 | `--allowJs` | *Not supported in MSBuild* | 26 | `--allowSyntheticDefaultImports` | TypeScriptAllowSyntheticDefaultImports | boolean 27 | `--allowUnreachableCode` | TypeScriptAllowUnreachableCode | boolean 28 | `--allowUnusedLabels` | TypeScriptAllowUnusedLabels | boolean 29 | `--baseUrl` | TypeScriptBaseUrl | File path 30 | `--charset` | TypeScriptCharset | 31 | `--declaration` | TypeScriptGeneratesDeclarations | boolean 32 | `--declarationDir` | TypeScriptDeclarationDir | File path 33 | `--diagnostics` | *Not supported in MSBuild* | 34 | `--emitBOM` | TypeScriptEmitBOM | boolean 35 | `--emitDecoratorMetadata` | TypeScriptEmitDecoratorMetadata | boolean 36 | `--experimentalAsyncFunctions` | TypeScriptExperimentalAsyncFunctions | boolean 37 | `--experimentalDecorators` | TypeScriptExperimentalDecorators | boolean 38 | `--forceConsistentCasingInFileNames` | TypeScriptForceConsistentCasingInFileNames | boolean 39 | `--help` | *Not supported in MSBuild* | 40 | `--inlineSourceMap` | TypeScriptInlineSourceMap | boolean 41 | `--inlineSources` | TypeScriptInlineSources | boolean 42 | `--init` | *Not supported in MSBuild* | 43 | `--isolatedModules` | TypeScriptIsolatedModules | boolean 44 | `--jsx` | TypeScriptJSXEmit | `React` or `Preserve` 45 | `--lib` | TypeScriptLib | Comma-separated list of strings 46 | `--listEmittedFiles` | *Not supported in MSBuild* | 47 | `--listFiles` | *Not supported in MSBuild* | 48 | `--locale` | *automatic* | Automatically set to PreferredUILang value 49 | `--mapRoot` | TypeScriptMapRoot | File path 50 | `--module` | TypeScriptModuleKind | `AMD`, `CommonJs`, `UMD`, `System` or `ES6` 51 | `--moduleResolution` | TypeScriptModuleResolution | `Classic` or `Node` 52 | `--newLine` | TypeScriptNewLine | `CRLF` or `LF` 53 | `--noEmit` | *Not supported in MSBuild* | 54 | `--noEmitHelpers` | TypeScriptNoEmitHelpers | boolean 55 | `--noEmitOnError` | TypeScriptNoEmitOnError | boolean 56 | `--noFallthroughCasesInSwitch` | TypeScriptNoFallthroughCasesInSwitch | boolean 57 | `--noImplicitAny` | TypeScriptNoImplicitAny | boolean 58 | `--noImplicitReturns` | TypeScriptNoImplicitReturns | boolean 59 | `--noImplicitThis` | TypeScriptNoImplicitThis | boolean 60 | `--noImplicitUseStrict` | TypeScriptNoImplicitUseStrict | boolean 61 | `--noUnusedLocals` | TypeScriptNoUnusedLocals | boolean 62 | `--noUnusedParameters` | TypeScriptNoUnusedParameters | boolean 63 | `--noLib` | TypeScriptNoLib | boolean 64 | `--noResolve` | TypeScriptNoResolve | boolean 65 | `--out` | TypeScriptOutFile | File path 66 | `--outDir` | TypeScriptOutDir | File path 67 | `--outFile` | TypeScriptOutFile | File path 68 | `--paths` | *Not supported in MSBuild* | 69 | `--preserveConstEnums` | TypeScriptPreserveConstEnums | boolean 70 | `--listEmittedFiles` | *Not supported in MSBuild* | 71 | `--pretty` | *Not supported in MSBuild* | 72 | `--reactNamespace` | TypeScriptReactNamespace | string 73 | `--removeComments` | TypeScriptRemoveComments | boolean 74 | `--rootDir` | TypeScriptRootDir | File path 75 | `--rootDirs` | *Not supported in MSBuild* | 76 | `--skipLibCheck` | TypeScriptSkipLibCheck | boolean 77 | `--skipDefaultLibCheck` | TypeScriptSkipDefaultLibCheck | boolean 78 | `--sourceMap` | TypeScriptSourceMap | File path 79 | `--sourceRoot` | TypeScriptSourceRoot | File path 80 | `--strictNullChecks` | TypeScriptStrictNullChecks | File path 81 | `--suppressExcessPropertyErrors` | TypeScriptSuppressExcessPropertyErrors | boolean 82 | `--suppressImplicitAnyIndexErrors` | TypeScriptSuppressImplicitAnyIndexErrors | boolean 83 | `--target` | TypeScriptTarget | `ES3`, `ES5`, or `ES6` 84 | `--traceResolution` | *Not supported in MSBuild* | 85 | `--types` | *Not supported in MSBuild* | 86 | `--typeRoots` | *Not supported in MSBuild* | 87 | `--watch` | *Not supported in MSBuild* | 88 | *MSBuild only option* | TypeScriptAdditionalFlags | *Any compiler option* 89 | 90 | ## What is supported in my version of Visual Studio? 91 | 92 | Look in your `C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets` file. 93 | The authoritative mappings between MSBuild XML tags and `tsc` compiler options live in there. 94 | 95 | ## ToolsVersion 96 | 97 | The value of `1.7` property in the project file identifies the compiler version to use to build (1.7 in this example). 98 | This allows a project to build against the save versions of the compiler on different machines. 99 | 100 | If `TypeScriptToolsVersion` is not specified, the latest compiler version installed on the machine will be used to build. 101 | 102 | Users using newer versions of TS, will see a prompt to upgrade their project on first load. 103 | 104 | ## TypeScriptCompileBlocked 105 | 106 | If you are using a different build tool to build your project (e.g. gulp, grunt , etc.) and VS for the development and debugging experience, set `true` in your project. 107 | This should give you all the editing support, but not the build when you hit F5. 108 | 109 | [Источник](http://typescript-lang.ru/docs/Compiler%20Options%20in%20MSBuild.html) -------------------------------------------------------------------------------- /pages/tutorials/ASP.NET 4.md: -------------------------------------------------------------------------------- 1 | # Настройка 2 | 3 | ## Установка TypeScript 4 | 5 | Если в вашей версии Visual Studio нет TypeScript, его можно установить для [Visual Studio 2015](http://www.microsoft.com/en-us/download/details.aspx?id=48593) или [Visual Studio 2013](https://www.microsoft.com/en-us/download/details.aspx?id=48739). 6 | В данном руководстве используется Visual Studio 2015. 7 | 8 | ## Создание нового проекта 9 | 10 | 1. Выберите **Файл** (**File**) 11 | 2. Выберите **Создать проект** (**New Project**) 12 | 3. Выберите **Visual C#** 13 | 4. Выберите **ASP.NET Web Application** 14 | 15 | ![Создание нового проекта ASP.NET](../../assets/images/tutorials/aspnet/new-asp-project.png) 16 | 17 | 5. Выберите **MVC** 18 | 19 | Флажок "Разместить в облаке" ("Host in the cloud") здесь снят, так как это пример локального проекта. 20 | ![Используйте шаблон MVC](../../assets/images/tutorials/aspnet/new-asp-project-template.png) 21 | 22 | Запустите приложение, и убедитесь, что оно работает. 23 | 24 | # Добавление TypeScript 25 | 26 | Следующий шаг — добавить папку для TypeScript. 27 | 28 | ![Создание новой папки](../../assets/images/tutorials/aspnet/new-folder.png) 29 | 30 | Назовем ее `src`. 31 | 32 | ![папка src](../../assets/images/tutorials/aspnet/src-folder.png) 33 | 34 | ## Добавление кода TypeScript 35 | 36 | Щелкните правой кнопкой на `src` и выберите **Создать элемент** (**New Item**). 37 | Затем выберите **Файл TypeScript** (**TypeScript File**), и назовите файл `app.ts`. 38 | 39 | ![Создание элемента](../../assets/images/tutorials/aspnet/new-item.png) 40 | 41 | ## Добавление кода примера 42 | 43 | Введите следующий код в `app.ts`. 44 | 45 | ```ts 46 | function sayHello() { 47 | const compiler = (document.getElementById("compiler") as HTMLInputElement).value; 48 | const framework = (document.getElementById("framework") as HTMLInputElement).value; 49 | return `Привет от ${compiler} и ${framework}!`; 50 | } 51 | ``` 52 | 53 | ## Настройка сборки 54 | 55 | Щелкните правой кнопкой мыши на проекте и выберите **Создать элемент** (**New Item**). 56 | Затем выберите **Файл конфигурации TypeScript** (**TypeScript Configuration File**), и используйте имя по умолчанию `tsconfig.json`. 57 | 58 | ![Создание tsconfig.json](../../assets/images/tutorials/aspnet/new-tsconfig.png) 59 | 60 | Замените содержимое файла `tsconfig.json`, которое было по умолчанию, на следующее: 61 | 62 | ```json 63 | { 64 | "compilerOptions": { 65 | "noImplicitAny": true, 66 | "noEmitOnError": true, 67 | "sourceMap": true, 68 | "target": "es5", 69 | "outDir": "./Scripts/App" 70 | }, 71 | "files": [ 72 | "./src/app.ts" 73 | ], 74 | "compileOnSave": true 75 | } 76 | ``` 77 | 78 | Это похоже на то, что было по умолчанию, но отличается следующим: 79 | 80 | 1. Устанавливается `"noImplicitAny": true`. 81 | 2. Указывается выходная директория `"outDir": "./Scripts/App"`. 82 | 3. Явно перечисляются входные файлы в `"files"`, не полагаясь на `"excludes"`. 83 | 4. Устанавливается `"compileOnSave": true`. 84 | 85 | Указывать `"noImplicitAny"` — неплохая идея, если вы пишете новый код; это поможет удостовериться, что вы по ошибке не напишете нетипизированный код. 86 | `"compileOnSave"` упрощает обновление кода в запущенном веб-приложении. 87 | См. [документацию на tsconfig.json](../tsconfig.json.md) для большей информации. 88 | 89 | ## Вызов скрипта из вида 90 | 91 | 1. В **Обозревателе решений** (**Solution Explorer**), откройте **Views** | **Home** | `Index.cshtml`. 92 | 93 | ![Открытие Index.cshtml](../../assets/images/tutorials/aspnet/open-index.png) 94 | 95 | 2. Замените код на следующий: 96 | 97 | ```html 98 | @{ 99 | ViewBag.Title = "Домашняя страница"; 100 | } 101 | 102 |
103 |
104 | Компилятор:
105 | Фреймворк: 106 |
107 | ``` 108 | 109 | ## Тестирование 110 | 111 | 1. Запустите проект. 112 | 2. Вы должны увидеть сообщение при заполнении полей ввода: 113 | 114 | ![Запущенное приложение](../../assets/images/tutorials/aspnet/running-demo.png) 115 | 116 | ## Отладка 117 | 118 | 1. Нажмите F12 в браузере Edge и выберите вкладку **Отладчик** (**Debugger**). 119 | 2. Откройте первую папку `localhost`, затем `src/app.ts`. 120 | 3. Поставьте точку останова на строку с `return`. 121 | 4. Заполните поля ввода и убедитесь, что точка останова срабатывает на TypeScript-коде, и все работает правильно. 122 | 123 | ![Приложение, остановленное но точке останова](../../assets/images/tutorials/aspnet/paused-demo.png) 124 | 125 | Это все, что нужно знать, чтобы применить TypeScript в проекте ASP.NET. 126 | Дальше мы задействуем Angular и напишем простое приложение для этого фреймворка. 127 | 128 | # Добавление Angular 2 129 | 130 | ## Загрузка зависимостей из NPM 131 | 132 | 1. Установите [PackageInstaller](https://github.com/madskristensen/PackageInstaller). 133 | 134 | 2. С помощью PackageInstaller установите Angular 2, systemjs и Typings. 135 | 136 | Щелкните правой кнопкой мыши на проекте и выберите **Quick Install Package**. 137 | 138 | ![Установка angular2](../../assets/images/tutorials/aspnet/packageinstaller-angular2.png) 139 | ![Установка systemjs](../../assets/images/tutorials/aspnet/packageinstaller-systemjs.png) 140 | ![Установка Typings](../../assets/images/tutorials/aspnet/packageinstaller-typings.png) 141 | 142 | 3. С помощью PackageInstaller установите файлы объявлений для es6-shim. 143 | 144 | Библиотека es6-shim включена в Angular для поддержки обещаний, но TypeScript все же нужны файлы объявлений для нее. 145 | В окне PackageInstaller выберите Typing вместо npm, и введите "es6-shim": 146 | 147 | ![Установка файлов объявлений es6-shim](../../assets/images/tutorials/aspnet/packageinstaller-es6-shim.png) 148 | 149 | ## Обновление tsconfig.json 150 | 151 | Теперь, когда Angular 2 и его зависимости установлены, нужно включить в TypeScript экспериментальную поддержку декораторов, а также включить в код объявления типов для es6-shim. 152 | В будущем декораторы и ES6 будут включены по умолчанию и данные настройки станут не нужны. 153 | Добавьте `"experimentalDecorators": true, "emitDecoratorMetadata": true` в `"compilerOptions"`, и `"./typings/index.d.ts"` в `"files"`. 154 | В последнюю очередь нужно добавить в `"files"` новый элемент для файла `"./src/model.ts"`, который мы создадим. 155 | Файл `tsconfig.json` теперь должен быть таким: 156 | 157 | ```json 158 | { 159 | "compilerOptions": { 160 | "noImplicitAny": false, 161 | "noEmitOnError": true, 162 | "sourceMap": true, 163 | "target": "es5", 164 | "experimentalDecorators": true, 165 | "emitDecoratorMetadata": true, 166 | "outDir": "./Scripts/App" 167 | }, 168 | "files": [ 169 | "./src/app.ts", 170 | "./src/model.ts", 171 | "./src/main.ts", 172 | "./typings/index.d.ts" 173 | ] 174 | } 175 | ``` 176 | 177 | ## Добавление в сборку цели CopyFiles 178 | 179 | Теперь нужно убедиться, что в процессе сборки будут копироваться файлы Angular. 180 | Для этого отредактируйте проект, щелкнув правой мышкой и выбрав 'Выгрузить проект' ('Unload'), а затем 'Изменить csproj' ('Edit csproj'). 181 | После элемента PropertyGroup с параметрами TypeScript добавьте ItemGroup и Target для копирования файлов Angular. 182 | 183 | ```xml 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | ``` 194 | 195 | Теперь щелкните правой кнопкой мыши на проекте и перезагрузите его ('Reload project'). 196 | В Обозревателе Решений должна появиться папка `node_modules`. 197 | 198 | ## Написание простого Angular-приложения на TypeScript 199 | 200 | Для начала измените код в `app.ts` на следующий: 201 | 202 | ```ts 203 | import {Component} from "angular2/core" 204 | import {MyModel} from "./model" 205 | 206 | @Component({ 207 | selector: `my-app`, 208 | template: `
Привет от {{getCompiler()}}
` 209 | }) 210 | class MyApp { 211 | model = new MyModel(); 212 | getCompiler() { 213 | return this.model.compiler; 214 | } 215 | } 216 | ``` 217 | 218 | Затем добавьте еще один файл TypeScript под именем `model.ts` в папку `src`. 219 | 220 | ```ts 221 | export class MyModel { 222 | compiler = "TypeScript"; 223 | } 224 | ``` 225 | 226 | И файл `main.ts` в `src`: 227 | 228 | ```ts 229 | import {bootstrap} from "angular2/platform/browser"; 230 | import {MyApp} from "./app"; 231 | bootstrap(MyApp); 232 | ``` 233 | 234 | Теперь измените код в `Views/Home/Index.cshtml` на следующий: 235 | 236 | ```html 237 | @{ 238 | ViewBag.Title = "Домашняя страница"; 239 | } 240 | 241 | 242 | 243 | 244 | 255 | Загрузка... 256 | ``` 257 | 258 | Этот код загружает приложение. 259 | При запуске приложения ASP.NET должен появиться элемент `div` с текстом "Загрузка...", который затем изменяется на "Привет от TypeScript". 260 | 261 | [Источник]() -------------------------------------------------------------------------------- /pages/tutorials/React & Webpack.md: -------------------------------------------------------------------------------- 1 | Это руководство призвано научить связывать TypeScript с [React](http://facebook.github.io/react/) и [webpack](http://webpack.github.io/). 2 | 3 | Предполагается, что вы уже используете [Node.js](https://nodejs.org/) и [npm](https://www.npmjs.com/). 4 | 5 | # Создание структуры проекта 6 | 7 | Начнем с создания новой папки. 8 | Мы назовем ее `proj`, однако ей можно дать любое необходимое имя. 9 | 10 | ```shell 11 | mkdir proj 12 | cd proj 13 | ``` 14 | 15 | Наш проект будет иметь следующую структуру: 16 | 17 | ```text 18 | proj/ 19 | +- src/ 20 | | +- components/ 21 | | 22 | +- dist/ 23 | ``` 24 | 25 | Файлы TypeScript будут находиться в папке `src`, обрабатываться компилятором TypeScript, затем webpack, и в итоге будет получен файл `bundle.js` в папке `dist`. 26 | Все создаваемые нами компоненты будут находиться в папке `src/components`. 27 | 28 | Давайте создадим эту структуру: 29 | 30 | ```shell 31 | mkdir src 32 | cd src 33 | mkdir components 34 | cd .. 35 | mkdir dist 36 | ``` 37 | 38 | # Инициализация проекта 39 | 40 | Давайте сделаем из этой папки npm-пакет. 41 | 42 | ```shell 43 | npm init 44 | ``` 45 | 46 | Вам зададут несколько вопросов. 47 | Для всех можно использовать вариант ответа по умолчанию, кроме вопроса о точке входа (`entry point:`). 48 | В качестве точки входа используйте `./dist/bundle.js`. 49 | Вы всегда можете вернуться и изменить все, что указали, в сгенерированном файле `package.json`. 50 | 51 | # Установка зависимостей 52 | 53 | Для начала убедимся, что TypeScript, Typings и webpack установлены глобально. 54 | 55 | ```shell 56 | npm install -g typescript typings webpack 57 | ``` 58 | 59 | Webpack — это инструмент, который упаковывает код и, опционально, все его зависимости в единый `.js`-файл. 60 | [Typings](https://www.npmjs.com/package/typings) — это менеджер пакетов для получения файлов объявлений. 61 | 62 | Добавим зависимости от React и React-DOM в файл `package.json`: 63 | 64 | ```shell 65 | npm install --save react react-dom 66 | ``` 67 | 68 | Затем добавим зависимости времени разработки от [ts-loader](https://www.npmjs.com/package/ts-loader) и [source-map-loader](https://www.npmjs.com/package/source-map-loader). 69 | 70 | ```shell 71 | npm install --save-dev ts-loader source-map-loader 72 | npm link typescript 73 | ``` 74 | 75 | Обе эти зависимости призваны связать TypeScript и webpack друг с другом. 76 | ts-loader помогает webpack собирать файлы TypeScript, используя стандартный файл конфигурации под именем `tsconfig.json`. 77 | source-map-loader использует сгенерированные TypeScript карты кода, чтобы помочь webpack создать *свои собственные* карты кода. 78 | Это позволит отлаживать итоговый выходной файл, словно исходный код на TypeScript. 79 | 80 | Связывание пакета TypeScript (с помощью команды `npm link`) позволяет использовать глобальную версию TypeScript вместо отдельной локальной копии. 81 | Если требуется именно локальная копия, запустите `npm install typescript`. 82 | 83 | И, наконец, используем Typings, чтобы получить файлы объявлений для React и ReactDOM: 84 | 85 | ```shell 86 | typings install --global --save dt~react 87 | typings install --global --save dt~react-dom 88 | ``` 89 | 90 | Опция `--global`, вместе с префиксом `dt~`, сообщает Typings, что файлы объявлений нужно получить из [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped), репозитория с созданными сообществом файлами `.d.ts`. 91 | 92 | Данная команда создаст файл под именем `typings.json`, и добавит в текущую директорию папку `typings`. 93 | 94 | # Добавление файла конфигурации TypeScript 95 | 96 | Файлы TypeScript придется объединить — и написанный вами код, и необходимые файлы объявлений. 97 | 98 | Для этого нужно создать файл `tsconfig.json`, содержащий список входных файлов и все настройки компиляции. 99 | Просто создайте новый файл под именем `tsconfig.json` в корневой директории проекта, и вставьте в него следующий код: 100 | 101 | ```json 102 | { 103 | "compilerOptions": { 104 | "outDir": "./dist/", 105 | "sourceMap": true, 106 | "noImplicitAny": true, 107 | "module": "commonjs", 108 | "target": "es5", 109 | "jsx": "react" 110 | }, 111 | "files": [ 112 | "./typings/index.d.ts", 113 | "./src/components/Hello.tsx", 114 | "./src/index.tsx" 115 | ] 116 | } 117 | ``` 118 | 119 | Здесь включается файл `typings/index.d.ts`, который был создан Typings. 120 | Этот файл автоматически включает все установленные зависимости. 121 | 122 | Больше узнать о файлах `tsconfig.json` можно [здесь](../tsconfig.json.html). 123 | 124 | # Написание кода 125 | 126 | Напишем наш первый TypeScript-файл с использованием React. 127 | Сначала создадим файл под именем `Hello.tsx` в `src/components` и напишем следующее: 128 | 129 | ```ts 130 | import * as React from "react"; 131 | 132 | export interface HelloProps { compiler: string; framework: string; } 133 | 134 | export class Hello extends React.Component { 135 | render() { 136 | return

Привет от {this.props.compiler} и {this.props.framework}!

; 137 | } 138 | } 139 | ``` 140 | 141 | Обратите внимание, что хотя в этом примере были применены классы, это не обязательно. 142 | Иные способы использования React (например, [функциональные компоненты без состояния](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions)) также должны работать. 143 | 144 | Теперь создадим в `src` файл `index.tsx` со следующим кодом: 145 | 146 | ```ts 147 | import * as React from "react"; 148 | import * as ReactDOM from "react-dom"; 149 | 150 | import { Hello } from "./components/Hello"; 151 | 152 | ReactDOM.render( 153 | , 154 | document.getElementById("example") 155 | ); 156 | ``` 157 | 158 | Мы импортировали наш компонент `Hello` в `index.tsx`. 159 | Обратите внимание, что в отличие от `"react"` и `"react-dom"`, здесь используется *относительный путь* к `index.tsx` — это важно. 160 | Если бы это было не так, то TypeScript искал бы этот файл в папке `node_modules`. 161 | 162 | Еще необходима страница, которая будет отображать компонент `Hello`. 163 | Создайте в корне проекта файл `index.html` со следующим содержимым: 164 | 165 | ```html 166 | 167 | 168 | 169 | 170 | Привет, React! 171 | 172 | 173 |
174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | ``` 184 | 185 | Обратите внимание, что здесь мы включаем файлы из `node_modules`. 186 | В пакетах React и React-DOM присутствуют `.js`-файлы, которые можно включать прямо на веб-страницу, и мы ссылаемся на них напрямую, чтобы не тратить времени. 187 | Но можно было бы скопировать эти файлы в другую директорию, или же разместить их в системе доставки контента (CDN). 188 | Facebook предоставляет доступные через CDN версии React; подробнее от этом можно [прочесть здесь](http://facebook.github.io/react/downloads.html#development-vs.-production-builds). 189 | 190 | # Создание файла конфигурации webpack 191 | 192 | Создайте файл `webpack.config.js` в корневой директории проекта. 193 | 194 | ```js 195 | module.exports = { 196 | entry: "./src/index.tsx", 197 | output: { 198 | filename: "./dist/bundle.js", 199 | }, 200 | 201 | // Включить карты кода для отладки вывода webpack 202 | devtool: "source-map", 203 | 204 | resolve: { 205 | // Добавить разрешения '.ts' и '.tsx' к обрабатываемым 206 | extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"] 207 | }, 208 | 209 | module: { 210 | loaders: [ 211 | // Все файлы с разрешениями '.ts' или '.tsx' будет обрабатывать 'ts-loader' 212 | { test: /\.tsx?$/, loader: "ts-loader" } 213 | ], 214 | 215 | preLoaders: [ 216 | // Все карты кода для выходных '.js'-файлов будет дополнительно обрабатывать `source-map-loader` 217 | { test: /\.js$/, loader: "source-map-loader" } 218 | ] 219 | }, 220 | 221 | // При импортировании модуля, чей путь совпадает с одним из указанных ниже, 222 | // предположить, что соответствующая глобальная переменная существует, и использовать 223 | // ее взамен. Это важно, так как позволяет избежать добавления в сборку всех зависимостей, 224 | // что дает браузерам возможность кэшировать файлы библиотек между различными сборками. 225 | externals: { 226 | "react": "React", 227 | "react-dom": "ReactDOM" 228 | }, 229 | }; 230 | ``` 231 | 232 | Поле `externals` может показаться интересным. 233 | Дело в том, что мы хотим избежать добавления в итоговый файл всех файлов React, поскольку это увеличило бы время сборки, и не позволило бы браузеру кешировать не изменившиеся библиотеки. 234 | 235 | В идеале можно было бы просто импортировать модуль React прямо в браузере, но большинство браузеров на сегодняшний день не поддерживают модулей. 236 | Вместо этого библиотеки используют традиционный подход с предоставлением одной глобальной переменой, например `jQuery` или `_`. 237 | Это называется шаблоном организации пространства имен ("namespace pattern"), и webpack позволяет использовать библиотеки, созданные на основе этого шаблона. 238 | Указав `"react": "React"`, мы позволяем webpack совершить некие магические действия, которые дадут возможность импортировать `"react"` из переменной `React`. 239 | 240 | Больше о настройке webpack можно узнать [здесь](http://webpack.github.io/docs/configuration.html). 241 | 242 | # Собираем все вместе 243 | 244 | Просто запустите: 245 | 246 | ```shell 247 | webpack 248 | ``` 249 | 250 | Теперь откройте `index.html` в любимом браузере, и все должно быть готово! 251 | Вы должны увидеть страницу с текстом "Привет от TypeScript и React!". 252 | 253 | [Источник](http://typescript-lang.ru/docs/tutorials/React%20&%20Webpack.html) -------------------------------------------------------------------------------- /pages/JSX.md: -------------------------------------------------------------------------------- 1 | # Введение 2 | 3 | [JSX](https://facebook.github.io/jsx/) является встраиваемым XML-подобным расширением синтаксиса JavaScript. 4 | Он должен трасформироваться в корректный JavaScript, однако семантика такого преобразования зависит от конкретной реализации. 5 | JSX завоевал популярность вместе с фреймворком [React](http://facebook.github.io/react/), но потом применялся и отдельно. 6 | TypeScript поддерживает встраивание, проверку типов и преобразование JSX в JavaScript напрямую. 7 | 8 | # Основы 9 | 10 | Чтобы начать использовать JSX, необходимо сделать следующее: 11 | 12 | 1. Назначить вашим файлам расширение `.tsx` 13 | 2. Включить опцию `jsx` 14 | 15 | TypeScript имеет два JSX режима: `preserve` и `react`. 16 | Эти режимы влияют только на стадию генерации - проверка типов не изменяется. 17 | Режим `preserve` сохраняет JSX в выходном коде, который далее передаётся на следующий шаг трансформации (e.g. [Babel](https://babeljs.io/)). 18 | Выходной код получит расширение `.jsx`. 19 | Режим `react` сгенерирует `React.createElement`, где уже не нужно трансформировать JSX перед применением, и код на выходе получит расширение `.js`. 20 | 21 | Режим | Вход | Выход | Выходное расширение файла 22 | -----------|-----------|------------------------------|-------------------------- 23 | `preserve` | `
` | `
` | `.jsx` 24 | `react` | `
` | `React.createElement("div")` | `.js` 25 | 26 | Вы можете указать режим либо с помощью флага командной строки `--jsx`, либо в соответствующей опции в вашем файле [tsconfig.json](./tsconfig.json.html). 27 | 28 | > *Замечание: Идентификатор `React` жёстко прописан в коде, поэтому необходимо сделать React доступным с заглавной буквы R.* 29 | 30 | # Оператор `as` 31 | 32 | Вспомним, как записывается декларирование типов: 33 | 34 | ```ts 35 | var foo = bar; 36 | ``` 37 | 38 | Здесь мы декларируем, что переменная `bar` будет иметь тип `foo`. 39 | Так как TypeScript также использует угловые скобки для декларирования типов, синтаксис JSX's становится труднее обработать. В результате TypeScript запрещает использование угловых скобок при декларировании типов в файлах `.tsx`. 40 | 41 | Чтобы исправить эту потерю функциональности в файлах `.tsx`, был добавлен новый оператор: `as`. 42 | Предыдущий пример можно переписать с использованием оператора `as`. 43 | 44 | ```ts 45 | var foo = bar as foo; 46 | ``` 47 | 48 | Оператор `as` доступен как в `.ts` так и в `.tsx` файлах и ведёт себя точно также, как и другой оператор декларирования. 49 | 50 | # Проверка типов 51 | 52 | Чтобы понять проверку типов в JSX, необходимо уяснить разницу между внутренними элементами и элементами, основанными на значении. 53 | В JSX-выражении ``, `expr` может означать как внутренний элемент окружения (например, `div` или `span` в окружении DOM), так и созданный вами пользовательский элемент. 54 | Это важно по следующим причинам: 55 | 56 | 1. В React внутренние элементы генерируются в виде строк (`React.createElement("div")`), а пользовательские компоненты нет (`React.createElement(MyComponent)`). 57 | 2. Типы атрибутов, передаваемых в JSX-элемент, получаются разными способами. 58 | Внутренние элементы должны быть известны по умолчанию, тогда как компоненты, скорее всего, будут создавать свои собственные наборы атрибутов. 59 | 60 | TypeScript использует [то же соглашение, что и React](http://facebook.github.io/react/docs/jsx-in-depth.html#html-tags-vs.-react-components), чтобы различать два вышеупомянутых случая. 61 | Внутренние элементы всегда начинаются с маленькой буквы, а элементы, основанные на значении, начинаются с заглавной. 62 | 63 | ## Внутренние элементы 64 | 65 | Система находит внутренние элементы с помощью специального интерфейса `JSX.IntrinsicElements`. 66 | По умолчанию, если этот интерфейс не определён, тип всех внутренних элементов не будет проверен. 67 | Однако если интерфейс определён, система будет искать имя внутреннего элемента как свойство интерфейса `JSX.IntrinsicElements`. 68 | Например: 69 | 70 | ```ts 71 | declare namespace JSX { 72 | interface IntrinsicElements { 73 | foo: any 74 | } 75 | } 76 | 77 | ; // ok 78 | ; // ошибка 79 | ``` 80 | 81 | В примере выше `` отработает нормально, но `` приведёт к ошибке, так как он не был определён в `JSX.IntrinsicElements`. 82 | 83 | > Замечание: Вы также можете определить универсальный строковый индексатор `JSX.IntrinsicElements`: 84 | >```ts 85 | >declare namespace JSX { 86 | > interface IntrinsicElements { 87 | > [elemName: string]: any; 88 | > } 89 | >} 90 | >``` 91 | 92 | ## Элементы-значения 93 | 94 | Система ищет элементы-значения по идентификаторам в пределах области видимости. 95 | 96 | ```ts 97 | import MyComponent from "./myComponent"; 98 | 99 | ; // ok 100 | ; // ошибка 101 | ``` 102 | 103 | Есть возможность ограничить тип элемента-значения. 104 | Но для этого необходимо ввести два новых термина: *тип класса элемента* (element class type) и *тип экземпляра элемента* (element instance type). 105 | 106 | В выражении `` *типом класса элемента* является тип `Expr`. 107 | Таким образом, в вышеприведённом примере, если `MyComponent` принадлежит классу ES6, типом класса будет именно этот класс. 108 | Если `MyComponent` является фабричной функцией, тип класса будет этой функцией. 109 | 110 | Как только тип класса установлен, тип экземпляра определяется объединением возвращаемых типов сигнатуры вызова типа класса и сигнатуры конструктора. 111 | Опять же, в случае класса ES6, типом экземпляра будет тип экземпляра этого класса, а в случае фабричной функции это будет тип возвращаемого функцией значения. 112 | 113 | ```ts 114 | class MyComponent { 115 | render() {} 116 | } 117 | 118 | // использование сигнатуры конструктора 119 | var myComponent = new MyComponent(); 120 | 121 | // element class type => MyComponent 122 | // element instance type => { render: () => void } 123 | 124 | function MyFactoryFunction() { 125 | return { 126 | render: () => { 127 | } 128 | } 129 | } 130 | 131 | // использование сигнатуры вызова 132 | var myComponent = MyFactoryFunction(); 133 | 134 | // element class type => FactoryFunction 135 | // element instance type => { render: () => void } 136 | ``` 137 | 138 | Также вызывает интерес тип элемента экземпляра, поскольку должна быть возможность назначить его `JSX.ElementClass`, в противном случае возникнет ошибка. 139 | По умолчанию `JSX.ElementClass` является`{}`, но он может быть дополнен, чтобы ограничить использование JSX только теми типами, которые соответствуют правильному интерфейсу. 140 | 141 | ```ts 142 | declare namespace JSX JSX { 143 | interface ElementClass { 144 | render: any; 145 | } 146 | } 147 | 148 | class MyComponent { 149 | render() {} 150 | } 151 | function MyFactoryFunction() { 152 | return { render: () => {} } 153 | } 154 | 155 | ; // ok 156 | ; // ok 157 | 158 | class NotAValidComponent {} 159 | function NotAValidFactoryFunction() { 160 | return {}; 161 | } 162 | 163 | ; // ошибка 164 | ; // ошибка 165 | ``` 166 | 167 | ## Проверка типа атрибута 168 | 169 | Для того, чтобы проверить типы атрибутов, сначала необходимо определить *тип атрибутов элемента* (element attributes type). 170 | Эта процедура немного отличается для внутренних элементов и элементов-значений. 171 | 172 | Для внутренних элементов это тип свойства в `JSX.IntrinsicElements` 173 | 174 | ```ts 175 | declare namespace JSX { 176 | interface IntrinsicElements { 177 | foo: { bar?: boolean } 178 | } 179 | } 180 | 181 | // типом атрибутов элемента 'foo' является '{bar?: boolean}' 182 | ; 183 | ``` 184 | 185 | Для элементов-значений вопрос немного усложняется. 186 | Тип атрибутов определяется типом *типом экземпляра элемента* (element instance type), который был установлен ранее. 187 | Какое свойство использовать, определяется с помощью `JSX.ElementAttributesProperty`. 188 | Оно должно быть объявлено единственным свойством, имя которого будет использоваться далее. 189 | 190 | ```ts 191 | declare namespace JSX { 192 | interface ElementAttributesProperty { 193 | props; // укажите имя свойства для дальнейшего использования 194 | } 195 | } 196 | 197 | class MyComponent { 198 | // укажите свойство типа экземпляра элемента 199 | props: { 200 | foo?: string; 201 | } 202 | } 203 | 204 | // типом атрибутов элемента 'MyComponent' является '{foo?: string}' 205 | 206 | ``` 207 | 208 | Тип атрибута элемента используется для проверки типов атрибутов в JSX. 209 | Поддерживаются опциональные и обязательные свойства. 210 | 211 | ```ts 212 | declare namespace JSX { 213 | interface IntrinsicElements { 214 | foo: { requiredProp: string; optionalProp?: number } 215 | } 216 | } 217 | 218 | ; // ok 219 | ; // ok 220 | ; // ошибка, не указано requiredProp 221 | ; // ошибка, requiredProp должно быть строкой 222 | ; // ошибка, unknownProp не существует 223 | ; // ok, потому что 'some-unknown-prop' не является корректным идентификатором 224 | ``` 225 | 226 | > Замечание: Если имя атрибута не является корректным JS-идентификатором (как атрибут `data-*`), это не будет считаться ошибкой, если не будет находиться в типе атрибутов элемента. 227 | 228 | Также можно использовать оператор расширения: 229 | 230 | ```JSX 231 | var props = { requiredProp: "bar" }; 232 | ; // ok 233 | 234 | var badProps = {}; 235 | ; // ошибка 236 | ``` 237 | 238 | # Тип результата JSX 239 | 240 | По умолчанию результирующим типом выражения JSX является тип `any`. 241 | Вы можете изменить тип путём определения интерфейса `JSX.Element`. 242 | Однако невозможно получить информацию о типах элемента, атрибутов или потомков JSX из интерфейса. 243 | Фактически это чёрный ящик. 244 | 245 | # Встраивание выражений 246 | 247 | JSX позволяет вставлять выражения между тегами, заключая их в фигурные скобки (`{ }`). 248 | 249 | ```JSX 250 | var a =
251 | {["foo", "bar"].map(i => {i / 2})} 252 |
253 | ``` 254 | 255 | Вышеприведённый код завершится ошибкой, так как вы не можете разделить строку на число. 256 | При использовании опции `preserve` вывод будет выглядеть так: 257 | 258 | ```JSX 259 | var a =
260 | {["foo", "bar"].map(function (i) { return {i / 2}; })} 261 |
262 | ``` 263 | 264 | # Интеграция с React 265 | 266 | Для работы JSX с React необходимо использовать [React typings](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/react). 267 | Эти типы определяют пространство имён `JSX` для корректного использования с React. 268 | 269 | ```ts 270 | /// 271 | 272 | interface Props { 273 | foo: string; 274 | } 275 | 276 | class MyComponent extends React.Component { 277 | render() { 278 | return {this.props.foo} 279 | } 280 | } 281 | 282 | ; // ok 283 | ; // ошибка 284 | ``` 285 | 286 | [Источник](http://typescript-lang.ru/docs/JSX.html) -------------------------------------------------------------------------------- /pages/Namespaces.md: -------------------------------------------------------------------------------- 1 | > **Замечание по поводу терминологии:** 2 | Важно отметить, что в TypeScript 1.5 изменилась номенклатура. 3 | "Внутренние модули" теперь называются "пространства имён". 4 | "Внешние модули" стали просто "модулями", чтобы согласовать терминологию с [ECMAScript 2015](http://www.ecma-international.org/ecma-262/6.0/), (а именно: `module X {` эквивалентен предпочитаемому в настоящее время `namespace X {`). 5 | 6 | # Введение 7 | 8 | Данный раздел документации описывает различные пути организации вашего кода в TypeScript с помощью пространств имён (бывш. "внутренние модули"). 9 | Согласно замечанию о терминологии, "внутренние модули" теперь называются "пространства имён". 10 | В дополнение к этому, везде, где раньше для декларирования внутреннего модуля использовалось ключевое слово `module`, теперь вместо него должно быть использовано ключевое слово `namespace`. 11 | Это позволяет упростить жизнь новым пользователям, не перегружая их терминами с похожими названиями. 12 | 13 | # Первые шаги 14 | 15 | Давайте начнём с программы, которую мы будем использовать в этом разделе документации в качестве примера. 16 | Мы написали несколько простых валидаторов строк, которые могут использоваться для проверки ввода пользователя на форме веб-страницы или для проверки формата стороннего файла с данными. 17 | 18 | ## Валидаторы в одиночном файле 19 | 20 | ```ts 21 | interface StringValidator { 22 | isAcceptable(s: string): boolean; 23 | } 24 | 25 | let lettersRegexp = /^[A-Za-z]+$/; 26 | let numberRegexp = /^[0-9]+$/; 27 | 28 | class LettersOnlyValidator implements StringValidator { 29 | isAcceptable(s: string) { 30 | return lettersRegexp.test(s); 31 | } 32 | } 33 | 34 | class ZipCodeValidator implements StringValidator { 35 | isAcceptable(s: string) { 36 | return s.length === 5 && numberRegexp.test(s); 37 | } 38 | } 39 | 40 | // Несколько тестовых примеров 41 | let strings = ["Hello", "98052", "101"]; 42 | 43 | // Валидаторы 44 | let validators: { [s: string]: StringValidator; } = {}; 45 | validators["ZIP code"] = new ZipCodeValidator(); 46 | validators["Letters only"] = new LettersOnlyValidator(); 47 | 48 | // Для каждой строки показывает, прошла ли она каждый валидатор 49 | for (let s of strings) { 50 | for (let name in validators) { 51 | let isMatch = validators[name].isAcceptable(s); 52 | console.log(`'${ s }' ${ isMatch ? "соответствует" : "не соответствует" } '${ name }'.`); 53 | } 54 | } 55 | ``` 56 | 57 | # Использование пространств имён 58 | 59 | Поскольку мы добавляем больше валидаторов, нам понадобится какая-нибудь организационная схема, которая позволит отслеживать наши типы и не беспокоиться по поводу пересечений с именами других объектов. 60 | Вместо того, чтобы помещать множество различных идентификаторов в глобальное пространство имён, давайте обернём наши объекты в новое. 61 | 62 | В данном примере мы перенесём все элементы, связанные с валидаторами, в пространство имён `Validation`. 63 | Поскольку мы хотим, чтобы наши интерфейсы и классы были доступны извне, мы поместим перед ними ключевое слово `export`. 64 | Напротив, переменные `lettersRegexp` и `numberRegexp` - лишь детали данной реализации, поэтому они не экспортируются и не будут видимы вне своего пространства имён. 65 | В коде тестового примера в конце файла нам нужно определить имена типов в том виде, в котором они будут использоваться вне нашего пространства имён, например `Validation.LettersOnlyValidator`. 66 | 67 | ## Валидаторы внутри пространства имён 68 | 69 | ```ts 70 | namespace Validation { 71 | export interface StringValidator { 72 | isAcceptable(s: string): boolean; 73 | } 74 | 75 | const lettersRegexp = /^[A-Za-z]+$/; 76 | const numberRegexp = /^[0-9]+$/; 77 | 78 | export class LettersOnlyValidator implements StringValidator { 79 | isAcceptable(s: string) { 80 | return lettersRegexp.test(s); 81 | } 82 | } 83 | 84 | export class ZipCodeValidator implements StringValidator { 85 | isAcceptable(s: string) { 86 | return s.length === 5 && numberRegexp.test(s); 87 | } 88 | } 89 | } 90 | 91 | // Несколько тестовых примеров 92 | let strings = ["Hello", "98052", "101"]; 93 | 94 | // Валидаторы 95 | let validators: { [s: string]: Validation.StringValidator; } = {}; 96 | validators["ZIP code"] = new Validation.ZipCodeValidator(); 97 | validators["Letters only"] = new Validation.LettersOnlyValidator(); 98 | 99 | // Для каждой строки показывает, прошла ли она каждый валидатор 100 | for (let s of strings) { 101 | for (var name in validators) { 102 | console.log(`"${ s }" - ${ validators[name].isAcceptable(s) ? "соответствует" : "не соответствует" } ${ name }`); 103 | } 104 | } 105 | ``` 106 | 107 | # Разбиение на несколько файлов 108 | 109 | По мере роста нашего приложения мы захотим разбить код на насколько файлов, чтобы облегчить его поддержку. 110 | 111 | ## Многофайловые пространства имён 112 | 113 | Здесь мы разобьём пространство имён `Validation` на несколько файлов. 114 | Несмотря на то, что код находится в разных файлах, он может относиться к одному пространству имён и воспринимается также, как если бы он был расположен в одном месте. 115 | Поскольку между файлами есть зависимости, мы добавим ссылочные теги, чтобы указать компилятору на связи между файлами. 116 | В остальном наш тестовый код не изменится. 117 | 118 | ##### Validation.ts 119 | 120 | ```ts 121 | namespace Validation { 122 | export interface StringValidator { 123 | isAcceptable(s: string): boolean; 124 | } 125 | } 126 | ``` 127 | 128 | ##### LettersOnlyValidator.ts 129 | 130 | ```ts 131 | /// 132 | namespace Validation { 133 | const lettersRegexp = /^[A-Za-z]+$/; 134 | export class LettersOnlyValidator implements StringValidator { 135 | isAcceptable(s: string) { 136 | return lettersRegexp.test(s); 137 | } 138 | } 139 | } 140 | ``` 141 | 142 | ##### ZipCodeValidator.ts 143 | 144 | ```ts 145 | /// 146 | namespace Validation { 147 | const numberRegexp = /^[0-9]+$/; 148 | export class ZipCodeValidator implements StringValidator { 149 | isAcceptable(s: string) { 150 | return s.length === 5 && numberRegexp.test(s); 151 | } 152 | } 153 | } 154 | ``` 155 | 156 | ##### Test.ts 157 | 158 | ```ts 159 | /// 160 | /// 161 | /// 162 | 163 | // Несколько тестовых примеров 164 | let strings = ["Hello", "98052", "101"]; 165 | 166 | // Валидаторы 167 | let validators: { [s: string]: Validation.StringValidator; } = {}; 168 | validators["ZIP code"] = new Validation.ZipCodeValidator(); 169 | validators["Letters only"] = new Validation.LettersOnlyValidator(); 170 | 171 | // Для каждой строки показывает, прошла ли она каждый валидатор 172 | for (let s of strings) { 173 | for (let name in validators) { 174 | console.log(""" + s + "" " + (validators[name].isAcceptable(s) ? " соответствует " : " не соответствует ") + name); 175 | } 176 | } 177 | ``` 178 | 179 | Поскольку здесь используется несколько файлов, необходимо убедиться, что загружен весь компилируемый код. 180 | Это можно сделать двумя способами. 181 | 182 | Во-первых, мы можем использовать объединённый вывод с помощью флага `--outFile`, который позволяет скомпилировать все входные файлы в один выходной JavaScript: 183 | 184 | ```Shell 185 | tsc --outFile sample.js Test.ts 186 | ``` 187 | 188 | Компилятор автоматически упорядочит выходной файл на основе ссылочных тегов, находящихся в файлах. Вы также можете напрямую указать каждый файл: 189 | 190 | ```Shell 191 | tsc --outFile sample.js Validation.ts LettersOnlyValidator.ts ZipCodeValidator.ts Test.ts 192 | ``` 193 | 194 | Кроме того, можно использовать пофайловую компиляцию (по умолчанию), при которой на каждый входной файл генерируется отдельный файл JavaScript. 195 | Если на выходе получается несколько JS-файлов, на веб-странице необходимо использовать тег ` 185 | 186 | 187 | 188 |
189 |
190 | Компилятор:
191 | Фреймворк: 192 |
193 | 194 | 195 | ``` 196 | 197 | ## Тестирование 198 | 199 | 1. Запустите проект. 200 | 2. При изменении полей ввода вы должны увидеть сообщение: 201 | 202 | ![Запущенное приложение](../../assets/images/tutorials/aspnet/running-demo.png) 203 | 204 | ## Отладка 205 | 206 | 1. Нажмите F12 в браузере Edge и выберите вкладку **Отладчик** (**Debugger**). 207 | 2. Откройте первую папку `localhost`, затем `src/app.ts`. 208 | 3. Поставьте точку останова на строку с `return`. 209 | 4. Заполните поля ввода и убедитесь, что точка останова срабатывает на TypeScript-коде, и все работает правильно. 210 | 211 | ![Приложение, остановленное но точке останова](../../assets/images/tutorials/aspnet/paused-demo.png) 212 | 213 | Это все, что нужно знать, чтобы применить TypeScript в проекте ASP.NET. 214 | Дальше мы задействуем Angular и напишем простое приложение для этого фреймворка. 215 | 216 | # Добавление Angular 2 217 | 218 | ## Загрузка зависимостей из NPM 219 | 220 | Чтобы установить Angular 2 и SystemJS, добавьте следующие элементы к `"dependencies"` в файле `package.json`: 221 | 222 | ```json 223 | "dependencies": { 224 | "angular2": "2.0.0-beta.11", 225 | "systemjs": "0.19.24", 226 | }, 227 | ``` 228 | 229 | ## Установка файлов объявлений для зависимостей 230 | 231 | Библиотека es6-shim включена в Angular для поддержки обещаний, но TypeScript все же нужны файлы объявлений для нее. 232 | Откройте командную строку, затем измените текущую директорию на директорию с исходными файлами: 233 | 234 | ```shell 235 | cd C:\Users\<имя_пользователя>\Documents\Visual Studio 2015\Projects\\src\ 236 | npm install -g typings 237 | typings install --global dt~es6-shim 238 | ``` 239 | 240 | ## Обновление tsconfig.json 241 | 242 | Теперь, когда Angular 2 и его зависимости установлены, нужно включить в TypeScript экспериментальную поддержку декораторов, а также включить в код объявления типов для es6-shim. 243 | В будущем декораторы и ES6 будут включены по умолчанию и данные настройки станут не нужны. 244 | Добавьте `"experimentalDecorators": true, "emitDecoratorMetadata": true` в `"compilerOptions"`, и `"./typings/index.d.ts"` в `"files"`. 245 | В последнюю очередь нужно добавить в `"files"` новый элемент для файла `"./src/model.ts"`, который мы создадим. 246 | Файл `tsconfig.json` теперь должен быть таким: 247 | 248 | ```json 249 | { 250 | "compilerOptions": { 251 | "noImplicitAny": true, 252 | "noEmitOnError": true, 253 | "sourceMap": true, 254 | "experimentalDecorators": true, 255 | "emitDecoratorMetadata": true, 256 | "target": "es5" 257 | }, 258 | "files": [ 259 | "./app.ts", 260 | "./model.ts", 261 | "./main.ts", 262 | "../typings/main.d.ts" 263 | ], 264 | "compileOnSave": true 265 | } 266 | ``` 267 | 268 | ## Добавление Angular к сборке с gulp 269 | 270 | Теперь нужно убедиться, что файлы Angular будут копироваться во время сборки. 271 | Нужно добавить: 272 | 273 | 1. Пути к библиотечным файлам. 274 | 2. Задачу `lib`, чтобы направить файлы в `wwwroot`. 275 | 3. Зависимость от `lib` к задаче `default`. 276 | 277 | Измененный файл `gulpfile.js` должен выглядеть так: 278 | 279 | ```xml 280 | /// 281 | /* 282 | Данный файл является главной точкой входа для объявления задач Gulp и 283 | использования плагинов. Щелкните здесь, чтобы узнать больше. 284 | http://go.microsoft.com/fwlink/?LinkId=518007 285 | */ 286 | 287 | var gulp = require('gulp'); 288 | var del = require('del'); 289 | 290 | var paths = { 291 | scripts: ['scripts/**/*.js', 'scripts/**/*.ts', 'scripts/**/*.map'], 292 | libs: ['node_modules/angular2/bundles/angular2.js', 293 | 'node_modules/angular2/bundles/angular2-polyfills.js', 294 | 'node_modules/systemjs/dist/system.src.js', 295 | 'node_modules/rxjs/bundles/Rx.js'] 296 | }; 297 | 298 | gulp.task('lib', function () { 299 | gulp.src(paths.libs).pipe(gulp.dest('wwwroot/scripts/lib')) 300 | }); 301 | 302 | gulp.task('clean', function () { 303 | return del(['wwwroot/scripts/**/*']); 304 | }); 305 | 306 | gulp.task('default', ['lib'], function () { 307 | gulp.src(paths.scripts).pipe(gulp.dest('wwwroot/scripts')) 308 | }); 309 | ``` 310 | 311 | Как и в прошлый раз, убедитесь, что после сохранения `gulpfile.js` Диспетчер выполнения задач увидел новую задачу `lib`. 312 | 313 | ## Написание простого Angular-приложения на TypeScript 314 | 315 | Для начала измените код в `app.ts` на следующий: 316 | 317 | ```ts 318 | import {Component} from "angular2/core" 319 | import {MyModel} from "./model" 320 | 321 | @Component({ 322 | selector: `my-app`, 323 | template: `
Привет от {{getCompiler()}}
` 324 | }) 325 | class MyApp { 326 | model = new MyModel(); 327 | getCompiler() { 328 | return this.model.compiler; 329 | } 330 | } 331 | ``` 332 | 333 | Затем добавьте еще один файл TypeScript под именем `model.ts` в папку `src`. 334 | 335 | ```ts 336 | export class MyModel { 337 | compiler = "TypeScript"; 338 | } 339 | ``` 340 | 341 | И файл `main.ts` в `src`: 342 | 343 | ```ts 344 | import {bootstrap} from "angular2/platform/browser"; 345 | import {MyApp} from "./app"; 346 | bootstrap(MyApp); 347 | ``` 348 | 349 | Теперь измените код в `index.html` на следующий: 350 | 351 | ```html 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 371 | 372 | 373 | 374 | Загрузка... 375 | 376 | 377 | ``` 378 | 379 | Этот код загружает приложение. 380 | При запуске приложения ASP.NET должен появиться элемент `div` с текстом "Загрузка...", который затем изменяется на "Привет от TypeScript". 381 | 382 | [Источник]() --------------------------------------------------------------------------------