typescript

The primitives: string, number, and boolean

  • string represents string values like "hello world"
  • number is for numbers like 32,no equivalent to int or flaot - everything is simply number.
  • boolean is for the two values true,and false.

Arrays

To specify the type of an array like [1,2,3] use number[]

Type Annotations on Variables 变量的类型注解

1
2
let name: string = "Alice";
// In most cases, though, this isn't needed. TS tries to automatically infer the types in your code.

Functions

1
2
3
4
5
function greet(name: string) {
console.log("Hello" + name.toUpperCase() + "!");
}
// error, paramter need a string.
greet(34);

return type

1
2
3
function getNumber(): number {
return 32;
}

Anonymous Functions匿名函数

1
2
3
4
5
6
7
8
const names = ["Alice", "Bob", "Eve"];

names.forEach(function (s){
// Property 'toUppercase' does not exits on type 'string', Did you mean 'toUpperCase'.
console.log(s.toUppercase());
})
// Even though the parameter `s` didn't have a type annotation,TypeScript used the types of the `forEach` function
// along with the inferred type of the Array, to determine the type `s` will have.

Optional Properties

to check Object is possible ‘undefined

1
2
3
4
5
6
function printName(obj: { first: string, last?: string }) {
// Object is possible 'undefined'
if (obj.last !== undefined) {
console.log(obj.last.toUpperCase());
}
}

Type Aliases

1
2
3
4
5
6
7
8
type Point = {
x: number;
y: number;
}

type ID = number | string;

type UserInputSanitizedString = string;

Interfaces

An interface declaration is another way to name an object type:

1
2
3
4
5
6
7
8
9
10
11
interface Point {
x: number;
y: number;
}

function printCoord(pt: Point) {
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
}

printCoord({x: 100, y: 1999 });

Literal Types 字面量类型

1
2
3
4
5

function printText(s: string, alignment: "left" | "right" | "center") {
// ...
}

Narrowing

typeof

  • string
  • number
  • bigint
  • boolean
  • symbol
  • undefined
  • object
  • function
    TypeScript knows that only a string value will have a typeof value “string”
    1
    2
    3
    4
    5
    6
    7
    function printId(id: number | string) {
    if (typeof id === 'string') [
    console.log(id.toUpperCase());
    ] else {
    console.log(id);
    }
    }
    if you have a union where all the members have something in common. For example, both arrays and strings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Return type is inferred as number[] | string
function getFirstThree(x: number[] | string) {
return x.slice(0,3);
}

fucntion printAll(strs: string | string[] | null) {
if (typeof strs === "object") {
// Object is possibly 'null'
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
} else {
// do nothing
}
}

function printAllFix(strs: string | string[] | null) {
if (strs && typeof strs === "object") {
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
}
}

// DON'T DO THIS!!!!!!!!!!!!!!!!!!!!
function printAll(strs: string | string[] | null) {
// !!!!!!!!!!!!!!!!
// DON'T DO THIS!
// KEEP READING
// !!!!!!!!!!!!!!!!
if (strs) {
if (typeof strs === "object") {
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
}
}
}

instanceof narrowing

1
2
3
4
5
6
7
function logValue(x: Date | string) {
if (x instanceof Date) {
console.log(x.toTCString())
} else {
console.log(x.toUpperCase())
}
}

Discriminated unions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

interface Shape {
kind: "circle" | "square";
radius?: number;
sideLength?: number;
}

function handleShape(shape: Shape) {
// oops!
if (shape.kind === "rect") {
// This condition will always return 'false' since the types '"circle"' | '"square"' and '"rect"' have no overlap.
}
}

function getArea(shape: Shape) {
return Math.PI * shape.radius ** 2;
// Object is possibly 'undefined'.
}

function getAreaFix(shape: Shape) {
if (shape.kind === 'circle') {
// we could try to use a non-null assertion (a `!` after `shape.radius`) to say that `radius` is definitely present.
return Math.PI * shape.radius! ** 2;
}
}


interface Circle {
  kind: "circle";
  radius: number;
}

interface Square {
  kind: "square";
  sideLength: number;
}

type Shape = Circle | Square;

function getArea(shape: Shape) {
  return Math.PI * shape.radius ** 2;
  // Property 'radius' does not exist on type 'Shape'
}

function getAreaFix(shape: Shape) {
  if (shape.kind === "circle") {
    return Math.PI * shape.radius ** 2; // shape: Circle
  }
}

// In this case, kind was that common property. The same checking works with `switch` statements as well. 

function getAreaSwitch(shape: Shape) {
  switch (shape.kind) {
    case "circle":
      return Math.PI * shape.radius ** 2;
    
    case "square":
      return shape.sideLength ** 2;
  }
}