typescript-學習使用ts-1

Hello World

新建 greeter.ts 並寫入如下內容:程序員

function greeter(person) {
    return "Hello, " + person;
}

let user = "Jane User";

document.body.innerHTML = greeter(user);

安裝編譯器:typescript

npm i -g typescript

編譯:shell

tsc greeter.ts

修改 greeter.ts 文件中的代碼,爲 greeter 函數的參數 person 加上類型聲明 :stringnpm

function greeter(person: string) {
    return "Hello, " + person;
}

let user = "Jane User";

document.body.innerHTML = greeter(user);

從新編譯執行。編程

讓咱們繼續修改:數組

function greeter(person: string) {
    return "Hello, " + person;
}

let user = [0, 1, 2];

document.body.innerHTML = greeter(user);

從新編譯,你將看到以下錯誤:函數

error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.

接口(Interface)

interface Person {
    firstName: string;
    lastName: string;
}

function greeter(person: Person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}

let user = { firstName: "Jane", lastName: "User" };

document.body.innerHTML = greeter(user);

類(Class)

class Student {
    fullName: string;
    constructor(public firstName: string, public middleInitial: string, public lastName: string) {
        this.fullName = firstName + " " + middleInitial + " " + lastName;
    }
}

interface Person {
    firstName: string;
    lastName: string;
}

function greeter(person : Person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}

let user = new Student("Jane", "M.", "User");

document.body.innerHTML = greeter(user);

變量聲明

var

  • 做用域
  • 重複聲明

let

  • 塊級做用域
  • 在同一個塊中不能重複聲明

const

  • 聲明同時必須賦值
  • 必定聲明不可改變
    • 對象能夠修改
  • 塊級做用域

let vs const

使用最小特權原則,全部變量除了你計劃去修改的都應該使用const。 基本原則就是若是一個變量不須要對它寫入,那麼其它使用這些代碼的人也不可以寫入它們,而且要思考爲何會須要對這些變量從新賦值。 使用 const也可讓咱們更容易的推測數據的流動。this

基本數據類型

布爾值

let isDone: boolean = false;

數字

let amount: number = 6;

字符串

  • 類型
  • 模板字符串
    • 支持換行
    • 支持內嵌表達式
  • 和 JavaScript 同樣,可使用雙引號,也可使用單引號,推薦單引號
let nickname: string = '張三';

還可使用模板字符串(換行 + 嵌入表達式):code

let nickname: string = `Gene`;
let age: number = 37;
let sentence: string = `Hello, my nickname is ${ nickname }.

I'll be ${ age + 1 } years old next month.`;

數組

TypeScript像JavaScript同樣能夠操做數組元素。 有兩種方式能夠定義數組。 第一種,能夠在元素類型後面接上[],表示由此類型元素組成的一個數組:對象

let list: number[] = [1, 2, 3];

第二種方式是使用數組泛型,Array<元素類型>

let list: Array<number> = [1, 2, 3];

元組

元組類型容許表示一個已知元素數量和類型的數組,各元素的類型沒必要相同。 好比,你能夠定義一對值分別爲stringnumber類型的元組。

// Declare a tuple type
let x: [string, number];
// Initialize it
x = ['hello', 10]; // OK
// Initialize it incorrectly
x = [10, 'hello']; // Error

Object

  • 容許賦任意值
  • 可是不能調用任意方法,即使它真的有
let foo: Object = {
  name: 'Jack',
  age: 18
}

知道便可,用的不多,沒有類型校驗和語法提示

Any

有時候,咱們會想要爲那些在編程階段還不清楚類型的變量指定一個類型。 這些值可能來自於動態的內容,好比來自用戶輸入或第三方代碼庫。 這種狀況下,咱們不但願類型檢查器對這些值進行檢查而是直接讓它們經過編譯階段的檢查。 那麼咱們可使用 any類型來標記這些變量:

let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean

Void

void類型像是與any類型相反,它表示沒有任何類型。 當一個函數沒有返回值時,你一般會見到其返回值類型是 void

function warnUser(): void {
  alert("This is my warning message");
}

聲明一個void類型的變量沒有什麼大用,由於你只能爲它賦予undefinednull

let unusable: void = undefined;

Null 和 Undefined

void類似,它們的自己的類型用處不是很大:

// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;

默認狀況下nullundefined是全部類型的子類型。 就是說你能夠把 nullundefined賦值給number類型的變量。

然而,當你指定了--strictNullChecks 標記,nullundefined 只能賦值給 void 和它們各自。 這能避免 不少常見的問題。許在某處你想傳入一個 stringnullundefined,你可使用聯合類型string | null | undefined

注意:咱們推薦儘量地使用--strictNullChecks ,由於它使你的代碼更嚴謹,能夠極大的減小出錯的概率。

類型推斷

有時候你會遇到這樣的狀況,你會比TypeScript更瞭解某個值的詳細信息。 一般這會發生在你清楚地知道一個實體具備比它現有類型更確切的類型。

經過類型斷言這種方式能夠告訴編譯器,「相信我,我知道本身在幹什麼」。 類型斷言比如其它語言裏的類型轉換,可是不進行特殊的數據檢查和解構。 它沒有運行時的影響,只是在編譯階段起做用。 TypeScript會假設你,程序員,已經進行了必須的檢查。

類型斷言有兩種形式。 其一是「尖括號」語法:

let someValue: any = "this is a string";

let strLength: number = (<string>someValue).length;

另外一個爲as語法:

let someValue: any = "this is a string";

let strLength: number = (someValue as string).length;

兩種形式是等價的。 至於使用哪一個大多數狀況下是憑我的喜愛;然而,當你在TypeScript裏使用JSX時,只有 as語法斷言是被容許的。

其它

  • ReadonlyArray<T> 去除了數組的全部可變方法,確保數組建立後不再能被修改

接口

TypeScript的核心原則之一是對值所具備的結構進行類型檢查。 它有時被稱作「鴨式辨型法」或「結構性子類型化」。 在TypeScript裏,接口的做用就是爲這些類型命名和爲你的代碼或第三方代碼定義契約。

基本示例

function printLabel(labelledObj: { label: string }) {
  console.log(labelledObj.label);
}

let myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);

類型檢查器會查看printLabel的調用。 printLabel有一個參數,並要求這個對象參數有一個名爲label類型爲string的屬性。 須要注意的是,咱們傳入的對象參數實際上會包含不少屬性,可是編譯器只會檢查那些必需的屬性是否存在,而且其類型是否匹配。 然而,有些時候TypeScript卻並不會這麼寬鬆

下面咱們重寫上面的例子,此次使用接口來描述:必須包含一個label屬性且類型爲string

interface LabelledValue {
  label: string;
}

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

可選屬性

接口裏的屬性不全都是必需的。 有些是隻在某些條件下存在,或者根本不存在。 可選屬性在應用「option bags」模式時很經常使用,即給函數傳入的參數對象中只有部分屬性賦值了。

interface SquareConfig {
  color?: string;
  width?: number;
}

function createSquare(config: SquareConfig): {color: string; area: number} {
  let newSquare = {color: "white", area: 100};
  if (config.color) {
    newSquare.color = config.color;
  }
  if (config.width) {
    newSquare.area = config.width * config.width;
  }
  return newSquare;
}

let mySquare = createSquare({color: "black"});

只讀屬性

一些對象屬性只能在對象剛剛建立的時候修改其值。 你能夠在屬性名前用 readonly來指定只讀屬性:

interface Point {
    readonly x: number;
    readonly y: number;
}

你能夠經過賦值一個對象字面量來構造一個Point。 賦值後, xy不再能被改變了。

let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!

readonly vs const

  • 常量使用 const
  • 對象屬性使用 readonly
相關文章
相關標籤/搜索