- Erasable
- Gradual
- Structural
- Generic
- Inferable
- Expressive
- Object-oriented
- Functional
TSConf 2020: Keynote - Anders Hejlsberg https://youtu.be/IGw2MRI0YV8?t=379
Apart from a few exceptions TypeScript does not impact the runtime JavaScript
interface StringProp { prop: string; }function getProp(arg: StringProp): string { return arg.prop; }
- enums
- namespace
- parameter properties
- experimental decorators
enum E { a = 1, b = 2, }
enum E { c = 3, }
const enum E2 { a = 10 ** 2 }
let x = E2.a;
// namespace
namespace YouView { export const version = 100; }
console.log(YouView.version);
// parameter properties
class Foo { constructor(public x: string) {} }
// experimental decorators declare var decorate: any;
@decorate() class Bar { @decorate method() {
} }
You can start with only JavaScript and gradually add types
- noEmitOnError: false
- noImplicitAny: false
- As opposed to nominal (by name)
function callMethod(arg: A): string { return arg.getString(); }
class B { private s = 'from b';
getString() { return this.s; } }
let b = new B(); callMethod(b);
- Enums
const enum Day { MONDAY, TUESDAY }
function setColour(c: Colour) {}
setColour(Colour.BLUE); setColour(0); setColour(Day.MONDAY);
interface GenericProp<T> { prop: T; }
function getProp<T>(arg: GenericProp<T>): T { return arg.prop; }
interface GenericProp<T> { prop: T; }
function getProp<T>(arg: GenericProp<T>): T { return arg.prop; }
let x = getProp({ prop: [1, 2, 3] }); // x: number[];
In computer science, the expressiveness of a language is the breadth of ideas that can be represented and communicated in that language.
https://en.wikipedia.org/wiki/Expressive_power_(computer_science)
// Adding props to objects function addProp<Obj, Prop extends string, Value>( obj: Obj, prop: Prop, value: Value ): Obj & { [key in Prop]: Value } { let newProp = {[prop]: value} as {[key in Prop]: Value}; return {...obj, ...newProp}; }
let x = addProp({ a: 1, b: '2' }, 'c', [3]); x.a; x.b; x.c;
// Manipulating strings let c = reverseString('abcdefgh');
type ReverseString<S extends string> = S extends '' ? '' : S extends `${infer Char}${infer Remaining}` ? `${ReverseString<Remaining>}${Char}` : '';
function reverseString<S extends string>(s: S) { return s.split('').reverse().join('') as ReverseString<S>; }
- Support for common OO patterns (abstract classes, private fields)
- Understands JS class runtime semantics
makeSound(): this { console.log(this.sound); return this; } }
class Dog extends Animal { sound = 'woof';
walk() { console.log('walk') } }
Dog.prototype.makeSound;
let pet = new Dog(); pet.makeSound().walk();
let pet2: Animal = new Dog(); pet2.makeSound().walk();
- Supports functional programming patterns
// composing function compose<A, B, C>( f1: Fun<A, B>, f2: Fun<B, C> ): Fun<A, C> { return (a) => f2(f1(a)); }
let makeArray = compose((x: string) => parseInt(x), n => new Array(n));
let result1 = makeArray('10');
// currying let add = (a: number, b: number) => a + b;
let add1 = add.bind(null, 1);
let oneHundred = add1(99);
Fin :)