TypeScript compiles into JavaScript.
TypeScript includes all of JavaScript, plus:
- static type checking
(todo fill in more)
1) Install Typescript Tools for Visual Studio.
2) If Visual Studio says that Web Developer Tools are not installed:
- Open Control Panel > Programs and Features > Visual Studio > Change
- Modify Visual Studio > Select Microsoft Web Development Tools under Windows and Web Development
- Click Next > Update
- Wait several minutes while it installs
3) Open Visual Studio > New Project > Other Languages > Typescript
continue at https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html
First, valid JavaScript is always valid TypeScript.
For instance, if you want an anonymous immediately invoking function, just write a JavaScript one:
(function() {
console.log("run");
})();
Convention:
interface MyInterface {
myFunction(x: string) {
return x;
}
}
As in JavaScript, names use camel case, starting with a lowercase letter.
Ex: oneTwoThree
Classes and Interfaces use camel case, starting with a capital letter.
Ex: OneTwoThree
// single line comments
/*
block comments
*/
This is the convetion for TypeScript comments. It is supported by tools like VSCode.
[TSDoc]
These comments are ignored unless they are on (immediately above) exported declarations.
Or if they are the Package Documentation.
Package Documentation
/**
* Package documentation summary.
*
* @remarks
* Package documentation remarks.
*
* @packageDocumentation
*/
/**
* Normal declaration documentation starts here
*/
export interface IWidget {
}
Documenting a function:
export class MyClass {
/**
* Summary of member function here - be brief.
*
* @remarks
* lengthy remarks here
*
* @privateRemarks
* remarks not intended for the public
*
* @example
* example usage here
* ```ts
* This is a TypeScript formatted code snippet
* ```
*
* @example
* another example here
*
* @param x - description of x
* @param y - description of y
* @returns description of return value
*/
public static MyFunction(x: number, y: number): number {
return x + y;
}
}
Documenting a variable:
/**
* Summary here
*
* @defaultValue `true`
*/
export public x: boolean = true;
Default value should only be used on fields/properties of a class/interface.
* literal value
* @defaultValue 3
*
* code span value
* @defaultValue `true`
*
* rich value
* @defaultValue An instance of the {@link Widget} object
Documenting a Getter and Setter:
/**
* Summary here
*/
export public get y(): string {
return "y";
}
export public set y(value: string) {
//do something
}
Matched Getter and Setters are considered a single declaration, so just put documentation on the first one.
Documenting a generic
/**
* A collection of items.
* @typeParam TItem - the type of the items in the collection
* @public
*/
export class ItemCollection<TItem extends object> {
private readonly _items: TItem[] = []
/**
* Add an item to the collection.
* @param item - the item to add
*/
public add(item: TItem): void {
this._items.push(item);
}
}
Override a member of a class:
export class MyClass extends MyBaseClass {
/**
* {@inheritDoc MyBaseClass.MyFunction}
* @override
*/
public static MyFunction() {
}
}
Indicates the member is overriding an inherited member.
Linking to another part of the documentation
export class MyClass {
/**
* Add link to {@link module_name#declaration_name | link_display_text}
* Add link to {@link local_declaration_name | link_display_text}
* Add link to {@link http://url.com | link_display_text}
*/
public static MyFunction() {
}
}
Inherit documentation from another declaration:
/**
* {@inheritDoc local_declaration_name}
* {@inheritDoc local_declaration_name.member_name}
* {@inheritDoc module_name#declaration_name}
*/
export class MyClass {
}
Will copy Summary, Remarks, Params, TypeParams, and Returns.
Documentation Modifiers: @alpha, @beta, @public, @internal, @virtual, @override, @sealed, @readonly, @deprecated
Documentation Modifiers are NOT related to TypeScript privacy modifiers.
Documentation Modifiers are applied recursively to all contained declarations.
export class MyClass {
/**
* Summary of function here
*
* @beta @virtual
*/
public static MyFunction() {
}
export class MyClass {
/**
* Summary of function here
* @deprecated Use {@link module_name#declaration_name.member_name} instead.
*/
public static MyFunction() {
}
}
@internal - only intended for use by other Modules by this maintainer - not by 3rd parties
@alpha, @beta - new functionality still being tested
@public - functionality officially released, will be supported
@eventProperty - only for class/interface properties - means the property returns an event object that handlers can attach to
Shorthand
/** @public */
export class MyClass {
}
Modules were previously called External Modules.
Modules are executed within their own scope, not the global scope.
Variables/functions/classes/etc declared in a Module are not visible outside the Module unless they are explicitly Exported.
An exported declaration from a Module must then be imported to be used elsewhere.
In Typescript, any file containing top-level import or export commands is considered a Module.
All other files are treated as Scripts.
In Typescript, a Script is any file with no top-level import or export commands.
Scripts exist in the global scope.
Namespaces were previously called Internal Modules.
A Declaration is any statement that declares a variable, function, class, type alias, or interface.
A Declaration can be exported from a Module.
Add the export keyword before the Declaration to make is accessible outside the current Module.
export interface MyValidator {
}
Alias an export
class MyValidator {
}
//not sure why the example lists both, do I need both?
export { MyValidator };
export { MyValidator as XyzValidator };
Re-export: export a declaration from another Module without importing it into your Module
export {XyzValidator as GeneralValidator) from "./MyInterface";
export * from "./File";
export * as Utilities from "./MyInterface";
Import declaractions that have been exported from other Modules.
import { MyValidator } from "./MyInterface";
let x = new MyValidator();
//cleaner syntax
import type { MyValidator } from "./MyInterface";
Imports declaration MyValidator from file "./MyInterface.ts"
Import multiple declarations
import { MyValidator, MyCalculator, MyUtilities } from "./MyInterface";
Alias a declaration
import { MyValidator as GeneralValidator } from "./MyInterface";
let x = new GeneralValidator();
Import everything into one variable
import * as Library from "./MyInterface";
let x = new Library.MyValidator();
Import just the side-effects (the changes to global state)
import "./MyInterface";
This is not recommended.
A module can optionally export one default export.
jQuery example:
declare let $: JQuery;
export default $;
Importing is different:
import $ from "jquery";
$("button.continue").html("Next step...");
Class example:
//export from MyModule.ts
export default class MyClass {
}
//import into Test.ts
import x from "./MyModule";
A variable in a class/interface.
A property (field+getter+setter) in a class/interface.
A function in a class/interface.
A function in global (or module) scope.
A variable in global (or module) scope.
myVariable: number = 3;
myVariable: string = "text";
let x: boolean = false;
As with JavaScript, all TypeScript numbers are floating-point numbers.
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
String literals:
let x: string = "text";
let y: string = 'text';
Template strings:
let fullName: string = `Bob Bobbington`;
let age: number = 37;
let sentence: string = `Hello, my name is ${ fullName } and I'm ${ age } years old.`;
let x: number[] = [1, 2, 3];
let y: Array<number> = [1, 2, 3];
let z:number = x[0];
Tuples have a fixed length, and can contain elements of different types.
let x:[string, number] = ["Steve", 86];
let y: string = x[0];
enum Color {Red, Green, Blue}
let c: Color = Color.Green; //1
let s: string = Color[1]; //Green
Default numbering starts at 0.
You can initialize the number explicitly.
enum Color {Red=5, Green, Blue}
Or explicit set all numbers
enum Flags {Red=1, Green=2, Blue=4, White=8}
Any is an anonymous type. These values come from dynamic content.
Any opts out of type checking.
let x: any = 4;
x = false;
x = "text";
Void is the absence of a value.
Void is commonly used as a return type to indicate no data is returned.
function print(message): void {
console.log(message);
}
With --strictNullChecks turned on, null and undefined can only be assigned to any-type variables.
Never is a type that never occurs.
It can be used as a return type instead of void.
function error(message: string): never {
throw new Error(message);
}
Never can be assigned to all other types.
Non-primitive types; not a number, string, boolean, bigint, symbol, null, or undefined.
function create(o: object | null): object {
return new Whatever();
}
Type assertions are for when you know more about the type than the compiler does.
A type assertions forces a conversion, with no checking or validation.
let x: any = "text";
let y: number = (<string>x).length;
let z: number = (x as string).length;