npm install --save-dev typescript tslint np watch
npm install --save-dev @types/node
package.json
{
"scripts": {
"dev": "watch 'npm run build' source",
"prebuild": "tslint --config .vscode/tslint.json --project source/tsconfig.json",
"build": "tsc -p source",
"pretest": "npm run build",
"test": "node build/index.test.js",
"test:watch": "watch 'npm test' source",
"prepublish": "npm run build",
"release": "np",
"clean": "rm -rf build node_modules"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"declaration": true,
"sourceMap": true,
"sourceRoot": "../source",
"outDir": "../build/"
},
"files": [
"index.ts",
"index.test.ts"
]
}
tsconfig.json
(cont.)
{
"compilerOptions": {
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"strict": true,
"alwaysStrict": true,
"strictNullChecks": true,
"forceConsistentCasingInFileNames": true,
"noImplicitThis": true,
"noUnusedLocals": true,
}
}
.vscode/task.json
{
"version": "0.1.0", "command": "npm", "isShellCommand": true,
"showOutput": "always", "suppressTaskName": true,
"tasks": [
{
"taskName": "build", "args": ["run", "build"],
"isBuildCommand": true,
"problemMatcher": [ "$tsc", "$tslint5" ]
},
{
"taskName": "test", "args": ["run", "test"],
"isTestCommand": true, "problemMatcher": [ "$tsc", "$tslint5" ]
}
]
}
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node", "request": "launch", "protocol": "inspector",
"name": "c99-build",
"preLaunchTask": "build",
"program": "${workspaceRoot}/build/index.js",
"args": [ "c99-build", "${workspaceRoot}/example/function.syspl" ],
"sourceMaps": true,
"outFiles": [ "${workspaceRoot}/build/**/*.js" ]
}
]
}
function f(x) {
return x
}
Unless "noImplicitAny": true
const name = "Name"
const message = name
const data = ["mixed data", 1, 2, true, null]
let name: string
let age: number
let names: string[]
let onlyObjects: Object
function f(x: int): int {
return x ** x
}
let whatever: any
let alwaysUndefined: undefined
let alwaysNull: null
function loopForever(): never {
while (true) { }
}
let record: { name: string, age: number }
let records: { name: string, age: number }[]
type Record = { name: string, age: number }
let record: Record
let records: Record[]
let play: (position: number) => Promise
function f(x: (position: number) => boolean): void {
if (position > 0 && x(position)
alert("playing")
}
let record: [string, number]
record = ["Smith", 38]
record[1]++
enum Color { Red, Green, Blue, White = 255 }
let color: Color
color = Color.Green
let a: any = 5
let b = a as number
let c = a
type Record = { name: string, age: number }
let extendedRecord: Record & { email: string }
type Record = { name: string, age: number }
let data: Record | string = "Foo"
data = { "Bar", 42 }
let encoding: "utf8" | "ascii" | "utf16"
encoding = "utf8"
encoding = "blabla" // compile error
let grade: 1 | 2 | 3 | 4 | 5
grade = 3
grade = 6 // compile error
"strictNullChecks": true,
function log(data: number[]) {
alert("values: " + data.map(d => d.toString().join(", "))
}
log([42, 13.37])
log([])
log(null) // compile time error
Fixes Tony Hoare billion dollar mistake.
function log(data: number[] | null | undefined) {
if (data) // type guard required
alert("values: " + data.map(d => d.toString().join(", "))
}
log([42, 13.37])
log([])
log(null) // no error
function log(data?: number[]) {
if (data) // type guard required
alert("values: " + data.map(d => d.toString().join(", "))
}
log(undefined) // no error
function f(data: number | Record | null | string): string {
return
typeof(data) == "number" ? (data ** data).toString() :
data instanceof Record ? data.age.toString() :
data || "null"
}
function hasName(data: any) data is { name: string } & any {
return typeof((data as { name: string }).name) == "string"
}
export class Test { }
export function RunTest() {}
index.ts
export { Test } from "./Test"
index.ts
import * as NameSpace from "./NameSpace"
export {
NameSpace,
}
import * as NameSpace from "./NameSpace"
new NameSpace.Test()
export class Test {
constructor() { }
}
export class Base {
constructor() { }
}
import { Base } from "./Base"
export class Test extends Base {
constructor() {
super()
}
}
export abstract class Base {
protected constructor() { }
abstract doThing()
}
import { Base } from "./Base"
export class Test extends Base {
constructor() {
super()
}
doThing() { }
}
public
by default
export class Test {
protected constructor() { }
private doSomething() { }
protected doSomethingElse() { }
}
compile time only - public when running
export class Test {
name: string
constructor() { }
}
export class Test {
private name: string
protected description: string
constructor() { }
}
export class Test {
readonly name: string
readonly description = "Directly initialized value"
constructor() {
this.name = "Constructor initialized value"
}
}
export class Test {
constructor(readonly name: string, private last = "", public value?: number) {
}
}
export interface Order {
count: number
price: number
volume: number
}
Good for receiving JSON-data.
export interface Handler {
raise: {
(message: Message): void
(message: string, level?: Level, type?: string, region?: Region): void
}
}
import { Handler } from "./Handler"
export class ConsoleHandler implements Handler {
raise(message: string | Message, level?: Level, type?: string, region?: Region): void {
if (!(message instanceof Message))
message = new Message(message as string, level, type, region)
console.error(message.toString())
}
}
interface Search {
(source: string, needle: string): boolean;
}
Simon Mika