let list: number[] = [1,2,3]; let list: Array<number> = [1,2,3]; let x: [string, number] = ['hello', 10];
enum Color { Red = 0, Green, Blue } let c: Color = Color.Green; enum Color {Red=1, Green=2, Blue=4} let d: string = Color[2]; // Green
let notSure: any = 4; let list: any[] = [1, true, 'free'];
functionwarnUser(): void{ console.log("This is my warning message"); }
let u: undefined = undefined;
let n: null = null;
# when using the --strictNullChecks flag, null and undefined are only assignable to any and their respective types (the one exception being that undefined is also assignable to void).
# JSX不适用 let someValue: any = "this is a string"; let strLength: number = (<string>someValue).length; let someValue: any = "this is a string"; let strLength: number = (someValue asstring).length;
let myArray: StringArray; myArray = ["Bob", "Fred"];
let myStr: string = myArray[0];
1 2 3 4 5
interface NumberDictionary { [index: string]: number; length: number; // ok, length is a number name: string; // error, the type of 'name' is not a subtype of the indexer }
interface SelectableControl extends Control { select(): void; }
class Button extends Control implements SelectableControl { select() {} }
class TextBox extends Control { select() {} }
class ImageControl implements SelectableControl { // Class 'ImageControl' incorrectly implements interface 'SelectableControl'. // Types have separate declarations of a private property 'state'. private state: any; select() {} }
functions
1 2 3 4 5 6
let myAdd: (x: number, y: number) =>number = function( x: number, y: number ): number{ return x + y; };
let result1 = buildName("Bob"); // works correctly now let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters let result3 = buildName("Bob", "Adams"); // ah, just right
Default-initialized parameters that come after all required parameters are treated as optional
let result1 = buildName("Bob"); // works correctly now, returns "Bob Smith" let result2 = buildName("Bob", undefined); // still works, also returns "Bob Smith" let result3 = buildName("Bob", "Adams", "Sr."); // error, too many parameters let result4 = buildName("Bob", "Adams"); // ah, just right
type Easing = "ease-in" | "ease-out" | "ease-in-out";
class UIElement { animate(dx: number, dy: number, easing: Easing) { if (easing === "ease-in") { // ... } elseif (easing === "ease-out") { } elseif (easing === "ease-in-out") { } else { // It's possible that someone could reach this // by ignoring your types though. } } }
let button = new UIElement(); button.animate(0, 0, "ease-in"); button.animate(0, 0, "uneasy"); // Argument of type '"uneasy"' is not assignable to parameter of type 'Easing'.
// Create a type which represents only one of the above types // but you aren't sure which it is yet. type NetworkState = | NetworkLoadingState | NetworkFailedState | NetworkSuccessState; functionnetworkStatus(state: NetworkState): string{ // Right now TypeScript does not know which of the three // potential types state could be.
// Trying to access a property which isn't shared // across all types will raise an error state.code; // Property 'code' does not exist on type 'NetworkState'. // Property 'code' does not exist on type 'NetworkLoadingState'. // By switching on state, TypeScript can narrow the union down in code flow analysis switch (state.state) { case"loading": return"Downloading..."; case"failed": // The type must be NetworkFailedState here, // so accessing the `code` field is safe return`Error ${state.code} downloading`; case"success": return`Downloaded ${state.response.title} - ${state.response.summary}`; } }
// Takes two objects and merges them together functionextend<Firstextends{}, Second extends {}>( first: First, second: Second ): First & Second { const result: Partial<First & Second> = {}; for (const prop in first) { if (first.hasOwnProperty(prop)) { (result as First)[prop] = first[prop]; } } for (const prop in second) { if (second.hasOwnProperty(prop)) { (result as Second)[prop] = second[prop]; } } return result as First & Second; }
const jim = extend(new Person("Jim"), ConsoleLogger.prototype); jim.log(jim.name);
classes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
class Animal { move(distanceInMeters: number = 0) { console.log(`Animal moved ${distanceInMeters}m.`); } }
class Dog extends Animal { bark() { console.log("Woof! Woof!"); } }
const dog = new Dog(); dog.bark(); dog.move(10); dog.bark();
public getElevatorPitch() { return`Hello, my name is ${this.name} and I work in ${this.department}.`; } }
let howard = new Employee("Howard", "Sales"); let john = new Person("John"); // Error: The 'Person' constructor is protected
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
class Octopus { readonly name: string; readonly numberOfLegs: number = 8; constructor(theName: string) { this.name = theName; } } let dad = new Octopus("Man with the 8 strong legs"); dad.name = "Man with the 3-piece suit"; // error! name is readonly.
class Octopus { readonly numberOfLegs: number = 8; constructor(readonly name: string) {} }
set fullName(newName: string) { if (newName && newName.length > fullNameMaxLength) { thrownewError("fullName has a max length of " + fullNameMaxLength); }
this._fullName = newName; } }
let employee = new Employee(); employee.fullName = "Bob Smith"; if (employee.fullName) { console.log(employee.fullName); }
abstract printMeeting(): void; // must be implemented in derived classes }
class AccountingDepartment extends Department { constructor() { super("Accounting and Auditing"); // constructors in derived classes must call super() }
printMeeting(): void { console.log("The Accounting Department meets each Monday at 10am."); }
let department: Department; // ok to create a reference to an abstract type department = new Department(); // error: cannot create an instance of an abstract class department = new AccountingDepartment(); // ok to create and assign a non-abstract subclass department.printName(); department.printMeeting(); department.generateReports(); // error: method doesn't exist on declared abstract type
let greeter1: Greeter; greeter1 = new Greeter(); console.log(greeter1.greet()); // "Hello, there"
let greeterMaker: typeof Greeter = Greeter; // give the type of the Greeter class itself rather than the instance type greeterMaker.standardGreeting = "Hey there!";
let greeter2: Greeter = new greeterMaker(); console.log(greeter2.greet()); // "Hey there!"
1 2 3 4 5 6 7 8 9 10
class Point { x: number; y: number; }
interface Point3d extends Point { z: number; }
let point3d: Point3d = { x: 1, y: 2, z: 3 };
enums
1 2 3 4
enum E { A = getSomeValue(), B // Error! Enum member must have initializer. can't auto computed }
1 2 3 4 5 6
enum Direction { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT" }
1 2 3 4 5 6 7 8 9
enum FileAccess { // constant members None, Read = 1 << 1, Write = 1 << 2, ReadWrite = Read | Write, // computed member G = "123".length }
let myGenericNumber = new GenericNumber<number>(); myGenericNumber.zeroValue = 0; myGenericNumber.add = function(x, y) { return x + y; };
let stringNumeric = new GenericNumber<string>(); stringNumeric.zeroValue = ""; stringNumeric.add = function(x, y) { return x + y; };
1 2 3 4 5 6 7 8
interface Lengthwise { length: number; }
functionloggingIdentity<TextendsLengthwise>(arg: T): T{ console.log(arg.length); // Now we know it has a .length property, so no more error return arg; }
type Name = string; type NameResolver = () =>string; type NameOrResolver = Name | NameResolver; functiongetName(n: NameOrResolver): Name{ if (typeof n === "string") { return n; } else { return n(); } }
type LinkedList<T> = T & { next: LinkedList<T> }; interface Person { name: string; } var people: LinkedList<Person>; var s = people.name; var s = people.next.name; var s = people.next.next.name; var s = people.next.next.next.name;
type Yikes = Array<Yikes>; // error
One difference is that interfaces create a new name that is used everywhere. Type aliases don’t create a new name — for instance, error messages won’t use the alias name. In the code below, hovering over interfaced in an editor will show that it returns an Interface, but will show that aliased returns object literal type. On the other hand, if you can’t express some shape with an interface and you need to use a union or tuple type, type aliases are usually the way to go.
1 2 3 4 5 6
type Alias = { num: number }; interface Interface { num: number; } declarefunctionaliased(arg: Alias): Alias; declarefunctioninterfaced(arg: Interface): Interface;
class BasicCalculator { publicconstructor(protected value: number = 0) {} public currentValue(): number { returnthis.value; } public add(operand: number): this { this.value += operand; returnthis; } public multiply(operand: number): this { this.value *= operand; returnthis; } // ... other operations go here ... }
class ScientificCalculator extends BasicCalculator { publicconstructor(value = 0) { super(value); } public sin() { this.value = Math.sin(this.value); returnthis; } // ... other operations go here ... }
let v = new BasicCalculator(2) .multiply(5) .add(1) .currentValue();
let v = new ScientificCalculator(2) .multiply(5) .sin() .add(1) .currentValue();
interface Car { manufacturer: string; model: string; year: number; } let taxi: Car = { manufacturer: "Toyota", model: "Camry", year: 2014 };
// Manufacturer and model are both of type string, // so we can pluck them both into a typed string array let makeAndModel: string[] = pluck(taxi, ["manufacturer", "model"]);
// If we try to pluck model and year, we get an // array of a union type: (string | number)[] let modelYear = pluck(taxi, ["model", "year"]);
global utility types
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Partial<T> : Constructs a typewith all properties of T set to optional. Readonly<T> : Constructs a typewith all properties of T set to readonly. Record<K,T> : Constructs a typewith a set of properties K of type T. Pick<K,T> : Constructs a type by picking the set of properties K from T. Omit<K,T> : Constructs a type by picking all properties from T and then removing K. Exclude<T,U> : Constructs a type by excluding from T all properties that are assignable to U. Extract<T,U> : Constructs a type by extracting from T all properties that are assignable to U. NonNullable<T> : Constructs a type by excluding null and undefinedfrom T. Parameters<T> : Constructs a tuple type of the types of the parameters of a functiontypeT. ConstructorParameters<T> : TheConstructorParameters<T> typeletsusextractallparametertypesofaconstructorfunctiontype. ReturnType<T> : ConstructsatypeconsistingofthereturntypeoffunctionT. InstanceType<T> : ConstructsatypeconsistingoftheinstancetypeofaconstructorfunctiontypeT. Required<T> : ConstructsatypeconsistingofallpropertiesofTsettorequired. ThisParameterType : Extractsthetypeofthethisparameterofafunctiontype, orunknownifthefunctiontypehasnothisparameter. OmitThisParameter : Removesthethisparameterfromafunctiontype. ThisType<T> : Thisutilitydoesnotreturnatransformedtype. Instead, itservesasamarkerforacontextualthistype. Notethatthe --noImplicitThisflagmustbeenabledtousethisutility.
Maybe you could buy me a cup of coffee.
Scan this qrcode
Open alipay app scan this qrcode, buy me a coffee!
Scan this qrcode
Open wechat app scan this qrcode, buy me a coffee!