TypeScript 從入門到精通

一膛腐、什么是 TypeScript

先看一下官網(wǎng)上對 TypeScript 的介紹铡俐。

圖1.png

關(guān)鍵詞:超集
言外之意 JavaScript 的所有用法 TypeScript 都支持结蟋。

關(guān)鍵詞:Type
TypeScript 強(qiáng)調(diào)也是其優(yōu)點(diǎn)之意是【類型】

為什么需要 Ts 呢或听?舉個(gè)小例子:
一個(gè)杯子可以裝水探孝,也可以當(dāng)筆筒裝雜物。但是誉裆,拿裝雜物的杯子些許顯得不太干凈顿颅。物有所用,各司其職足丢。
Js 是弱類型可以定義 number 類型粱腻,可以定義 string 類型,這就并未各司其職斩跌。
所以绍些,這就誕生了 Ts

【前端經(jīng)常遇見的類型問題]

image.png

二、TypeScript 的安裝及運(yùn)行

安裝:npm install -g typescript 或者 yarn add global typescript
確認(rèn)是否安裝成功: tsc -v

在官網(wǎng)中(中文網(wǎng) -- 練習(xí))可以將 Ts 轉(zhuǎn)換為 Js

圖2.png

瀏覽器會識別 html / css / js耀鸦。識別不了 ts柬批,所以 ts 編譯轉(zhuǎn)變?yōu)闉?js啸澡。
https://jkchao.github.io/typescript-book-chinese/compiler/overview.html#%E6%96%87%E4%BB%B6%EF%BC%9Autilities

打開編輯器(確保在node/npm/typescript都成功的前提下)
第一步:新建文件夾 TS-APP
第二步:TS-APP下面新建一個(gè)index.html文件。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="./app.js"></script>
</body>
</html>

在<script src="./app.js"></script>若src="./app.ts"會報(bào)錯(cuò)

圖3.png

第三步:在TS-APP下面新建一個(gè)app.ts文件

class Greeter {
  greeting: string;
  constructor(message: string) {
      this.greeting = message;
  }
  greet() {
      return "Hello, " + this.greeting;
  }
}

let greeter = new Greeter("world");

let button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function() {
  alert(greeter.greet());
}

document.body.appendChild(button);

要想在瀏覽器運(yùn)行起來氮帐,需要將 app.ts 編譯轉(zhuǎn)換為 app.js嗅虏。此時(shí)就要進(jìn)行此命令: tsc app.ts
?運(yùn)行完此命令之后,會自動(dòng)生成一個(gè) app.js 文件上沐。此時(shí)瀏覽器打開皮服,效果如下:

圖4.png

問答區(qū):如果想同時(shí)運(yùn)行多個(gè) ts 文件該如何操作。
此時(shí)需要進(jìn)行此命令 tsc --init
命令執(zhí)行成功之后参咙,會自動(dòng)生成一個(gè) tsConfig.json 文件冰更,此文件則會將幫助所有的 ts 文件編譯轉(zhuǎn)換為相應(yīng)的 js 文件。
?運(yùn)行所有 ts 文件昂勒,tsc 即可蜀细,則會全部轉(zhuǎn)換

圖6.png

在此處,插播推薦兩個(gè)插件:
Live Server(能夠保存的時(shí)候戈盈,自動(dòng)更改)
TypeScript Auto Compiler(能夠保存之后奠衔,不需要執(zhí)行 tsc 命令,自動(dòng)會生成相應(yīng)的 js 文件)

三塘娶、TypeScript 入門

(一)TypeScript -- 基本數(shù)據(jù)類型和報(bào)錯(cuò)解析

為了讓程序有價(jià)值归斤,我們需要能夠處理最簡單的數(shù)據(jù)單元:數(shù)字,字符串刁岸,結(jié)構(gòu)體脏里,布爾值等。 TypeScript支持與JavaScript幾乎相同的數(shù)據(jù)類型虹曙,此外還提供了實(shí)用的枚舉類型方便我們使用迫横。

// 基本數(shù)據(jù)類型
let num = 25;
let float = 25.5;
let hex = 0xf000;  // 16進(jìn)制
let binary = 0b1001; // 2進(jìn)制
let octal = 0o733;  // 8進(jìn)制

// 重新賦值
num = '25';  // 會報(bào)錯(cuò),可以在終端編寫 tsc 進(jìn)行查看錯(cuò)誤?酝碳,如下圖7.

// ts原型
let num = 25;
// 等同于
// let num: number = 25;
圖7.png
其他數(shù)據(jù)類型:string 矾踱、boolean 、 any

??注意:在如下例子中:anything 賦予任何值都不會報(bào)錯(cuò)疏哗,是因?yàn)橹皇墙o anything 開辟了一個(gè)空間呛讲,但是并沒有定義其類型。在項(xiàng)目中返奉,盡量避免需用 any贝搁,不太利于后期維護(hù)。

//  boolean
// ts原型
let isLogin = false;
// 等同于
// let isLogin: string = false;

// **----------------------** // 

// string
let str: string = 'hello Tc';

// **----------------------** // 

// any
let anything; // 等同于 let anything: any
// 沒報(bào)錯(cuò)的原因芽偏,只是開辟了一個(gè)空間雷逆,但是沒有定義其類型
anything = 25;
anything = 'hello'

(二)TypeScript -- 數(shù)組 元組 枚舉

// 數(shù)組 元組 枚舉
let names: Array<string> = ['hello', 'word'];
// console.log(names[0]); // hello
// names[0] = 100; // 報(bào)錯(cuò),不能將類型“100”分配給類型“string”哮针。
// names[0] = 'yes';

let number: number[] = [1, 2, 3];
let anyArray: any[] = [1, 'hello', true];

// **----------------------** // 

// 元組
let colors: [string, number] = ['hello', 99];
// let colors: [string, number] = [99, 'hello']; // 會報(bào)錯(cuò)

// **----------------------** // 
// 枚舉
enum Color{
  Black,
  Yellow,
  Red,
}
// let myColor: Color = Color.Black; // 輸出為 0
// let myColor: Color = Color.Yellow; // 輸出為 1
// 若Yellow = 100, 則Red為101

此枚舉類型关面,轉(zhuǎn)換為 js 的時(shí)候是函數(shù)形式

var Color;
(function (Color) {
    Color[Color["Black"] = 0] = "Black";
    Color[Color["Yellow"] = 1] = "Yellow";
    Color[Color["Red"] = 2] = "Red";
})(Color || (Color = {}));
// let myColor: Color = Color.Black; // 輸出為 0
// let myColor: Color = Color.Yellow; // 輸出為 1
// 若Yellow = 100, 則Red為101

控制臺輸出:{0: "Black", 1: "Yellow", 2: "Red", Black: 0, Yellow: 1, Red: 2}

(三)函數(shù)相關(guān)類型

// 函數(shù)的相關(guān)類型
function returnValue() {
  return 'hello';
}
// console.log(returnValue()); // hello

// 規(guī)范寫法
function returnNum(): number { // 定義其返回值類型
  return 520;
}

// **----------------------** // 

// 若函數(shù)返回值 -- 空
function sayHello(): void {
  console.log('hello @@@@@');
}
sayHello();


// **----------------------** // 

// 參數(shù)類型
// 不標(biāo)準(zhǔn)寫法,已經(jīng)知道value1和value2的類型坦袍。
// 報(bào)錯(cuò)內(nèi)容:參數(shù)“value1”隱式具有“any”類型。
// function sumVal(value1, value2) {
//   return value1 + value2;
// }

function sumVal1(value1: number, value2: number): number {
  return value1 + value2;
  // return value1 * value2; // 如果兩個(gè)參數(shù)中有一個(gè)不是數(shù)值 那么返回的是NAN等太。但是若為0或者''捂齐,返回0。
}
console.log(sumVal1(1, 2)); // 3
// console.log(sumVal1(1, ''));

function sumVal2(value1: number, value2: string): string {
  return value1 + value2;
}
console.log(sumVal2(1, 'hello')); // 1hello

// **----------------------** // 

// 函數(shù)類型
let myFunc: (a: number, b: number) => number;
// 若函數(shù)為定義類型缩抡,如下則都可以賦值不同類型奠宜。
// myFunc = sayHello;
// myFunc();
myFunc = sumVal1; // 將函數(shù) sumVal1 賦予給 myFunc
console.log(myFunc(5, 5));   // 10

??注意:在最開始入 ts 坑時(shí),除開會寫 any 之外瞻想。印象最深刻的是 void压真。fuc(): void或者fuc: () => void。類似這樣的寫法都沒少寫蘑险。但是滴肿,碰到 .then。一報(bào)錯(cuò)就改成 any佃迄。
void 其實(shí)是代表函數(shù)返回值為時(shí)才使用的泼差。所以,不言而喻呵俏,.then 為什么會報(bào)錯(cuò)了堆缘。

??any,有人開玩笑說:把 TS 用成 AnyScript 的人開除普碎。如果項(xiàng)目中經(jīng)常使用any吼肥,則失去了TS本身最大的意義

(四)對象 object & type

// 對象 object & type
let listObj = {
  name: 'Danile',
  age: 31
};

// 不正確寫法
//  報(bào)錯(cuò)內(nèi)容:需要去包含 name 和 age 兩個(gè)屬性
// listObj = {}; 

// 報(bào)錯(cuò)內(nèi)容:不能包含別的屬性
// listObj =  {
//   n: 'hello',
//   a: 12,
// }

// 最規(guī)范寫法
// let listObj(name: string, age: number) = {
//   name: 'Danile',
//   age: 31
// };

// **----------------------** // 

// 稍微復(fù)雜對象類型
let complex: { data: number[], myFunc: (item: number) => number[] } = {
  data: [1, 2, 3],
  myFunc: function(item: number): number[] {
    this.data.push(item);
    return this.data;
  }
}
// console.log(complex.myFunc(520));

// **----------------------** // 

// type 生成類型
// type MyType = { data: number[], myFunc: (item: number) => number[] };
interface MyType { data: number[], myFunc: (item: number) => number[] };

let complex2: MyType = {
  data: [1, 2, 3],
  myFunc: function(item: number): number[] {
    this.data.push(item);
    return this.data;
  }
}
console.log(complex2.myFunc(520));

?type 和 interface 的區(qū)別?

  • 其中 interface 可以如下合并多個(gè)麻车,而 type 只能使用 & 類進(jìn)行連接缀皱。
interface A {
a: number;
}
interface A {
 b: number;
}
const a: A = {
 a: 3,
 b: 4
}

interface 可以繼承 , type 不可以繼承(type已經(jīng)可以繼承绪氛、實(shí)現(xiàn)了唆鸡。是2.X版本改的)

(五)union type(聯(lián)合類型) 檢查類型 null undefined never

// union type 檢查類型 null undefined never
// union type
let unionType: number | string | boolean = 12;
unionType = '12';
unionType = true;


// 檢查類型
let checkType = 10;
if (typeof checkType == 'number') {
  console.log('number')
}

// null 和 undefined
// let myNull = 12;
// myNull = null; // 如果"strict": false的時(shí)候則不會有問題

let myNull = null;
myNull = undefined;  

// never
// never類型是任何類型的子類型涝影,也可以賦值給任何類型枣察;然而,沒有類型是never的子類型或可以賦值給never
// 類型(除了never本身之外)燃逻。及時(shí)any也不可以賦值給never序目。通常表現(xiàn)為拋出異常或無法執(zhí)行到終點(diǎn)(例如無限循環(huán))

let x: never;
// x = 123; // 報(bào)錯(cuò):不能將類型“123”分配給類型“never”伯襟。

// never的應(yīng)用場景 拋出異常
function error(message: string): never {
  throw new Error(message);
}

// 死循環(huán)
function loop(): never {
  while (true) {}
}

let y: number;
y = ( () => {
  throw new Error('message');
})();

字面量類型:字面量也就是 JavaScript 基元類型具體的值猿涨。而在 TypeScript 中,我們可以將字面量作為一種自定義的類型姆怪,這種類型被稱為字面量類型

type China = 'China';
let country: China = 'China';  // ok
country = 'America';  // error: Type '"America"' is not assignable to type '"China"'.
null 和 undefined

當(dāng)你指定了--strictNullChecks標(biāo)記叛赚,null和undefined只能賦值給void和它們各自澡绩。 這能避免 很多常見的問題(防止項(xiàng)目aa.bb 取不到值等情況)。

(六)class 類(屬性俺附,方法)| 繼承

?區(qū)分 public protected private 的區(qū)別
public: 公共的
private: 當(dāng)成員被標(biāo)記成 private時(shí)肥卡,它就不能在聲明它的類的外部訪問。
protected: protected修飾符與 private修飾符的行為很相似事镣,但有一點(diǎn)不同步鉴, protected成員在派生類中仍然可以訪問

// class 類(屬性,方法)
class Person {
  public name: string;
  protected gender: string;
  private age: number = 27;
  // public username: string; 


  constructor(name: string, gender: string, public username: string) {
    this.name = name;
    this.username = username;
    this.gender = gender;
  }

  printAge(age: number) {
    this.age = age;
    console.log(this.age);
  }

  setGender(gender: string) {
    this.gender = gender;
    console.log(this.gender);
  }
}

const person = new Person('Danile', '女', 'Ts');
console.log(person.name, person.username);

person.printAge(30);
person.setGender('男');


// **----------------------** // 
// 繼承
// 子類可以獲得父類所有公開的
class Studen extends Person {
  studentId: number;
  constructor(name: string, username: string, studentId: number) {
    super(name, username);
    this.studentId = studentId;
  }
}

const student = new Studen('Kris', 'Ts', 23);
console.log(student.name, student.username, student.studentId);
console.log(student)
把類當(dāng)做接口使用

類定義會創(chuàng)建兩個(gè)東西:類的實(shí)例類型和一個(gè)構(gòu)造函數(shù)璃哟。 因?yàn)轭惪梢詣?chuàng)建出類型氛琢,所以你能夠在允許使用接口的地方使用類。

   x: number;
   y: number;
}
interface Point3d extends Point {
   z: number;
}
let point3d: Point3d = {x: 1, y: 2, z: 3};

(七) class set get修飾詞 用于隔離私有屬性和可公開屬性

// 1.class set get修飾詞 用于隔離私有屬性 和 可公開屬性
// 2.class 靜態(tài)屬性和方法

class Person1 {
  private _name: string = 'Danile_getName';

  // 私用屬性賦值
  set setName(value: string) {
    this._name = value;
  }

  // 私有屬性取值
  get getName() {
    return this._name;
  }
}

let person1 = new Person1();
console.log(person1.getName);   //  Danile_getName
person1.setName = 'Danile_setName';
console.log(person1.getName);  //  Danile_setNames

對于 set 和 get 還可以應(yīng)用在校驗(yàn)等場景随闪⊙羲疲看如下圖:

圖8

(八)namespace 命名空間

// namespace 命名空間
namespace myMath {
  export const PI = 3.14;

  export function sumValue(num1: number, num2: number): number {
    return num1 + num2;
  }
  
  export function calcCircle(value: number) {
    return value * PI
  }
}

const PI = 2.88;

console.log(myMath.sumValue(5, 10));  // 10
console.log(myMath.PI);  // 3.14

console.log(PI); //  2.88

命名空間最大的好處是:隔離環(huán)境變量的污染

若將命名空間放不到不同的文件夾,該如何铐伴?

// sumValue.ts
namespace myMath {
  export function sumValue(num1: number, num2: number): number {
    return num1 + num2;
  }
}

// calcCircle.ts
namespace myMath {
  export const PI = 3.14;
  export function calcCircle(value: number) {
    return value * PI
  }
}

// nameSpace.ts
console.log(myMath.sumValue);  // 會報(bào)錯(cuò)的障般,找不到myMath的文件
console.log(myMath.calcCircle);

// 解決方案1: 在app.ts(最外層入口)加,<script src="sumValue.js"></script>
// 解決方案2: tsc --outfile app.js sumValue.ts calcCircle.ts app.ts
// app.js 是輸入文件
// sumValue.ts calcCircle.ts app.ts 合并為app.js文件

謹(jǐn)慎使用 --outFile

多重命名空間

// 多重命名空間 
namespace myMath {
  export namespace Circle {
    export const PI = 3.14;

    export function sumValue(num1: number, num2: number): number {
      return num1 + num2;
    }
    
    export function calcCircle(value: number) {
      return value * PI
    }
  }
}

// 若 namespace Circle 不進(jìn)行export驱证。則myMath.Circle取不到延窜。
console.log(myMath.Circle.sumValue(5, 10));

reference -- 引入ts文件,寫法: ///

// 引入文件
// 它是一種注釋抹锄,告訴typescript編譯器逆瑞,當(dāng)前文件使用了哪些聲明文件,以幫助編輯器提示信息伙单,
// 及編譯器檢查類型获高。這種注釋很重要,如果后面的路徑不對吻育,則編譯會失敗念秧。

/// <reference path="text_1.ts" />

// **----------------------** // 
// 多個(gè)文件打包
tsc --outFile app.ts

(九)interface

// interface 接口
interface PersonInterface {
  name: string,
  ages: number, // :號,是必傳
  sex?: string, // 布疼?:,是非必傳
  readonly salary: number, // 只讀不能修改,  personInfo.salary = 1000(會報(bào)錯(cuò))
  [propName: string]: any, // 給任何名字
  greet(): void,
}

// type Person2 = { name: string, ages: number }

let personInfo: PersonInterface = {
   name: 'Danile',
   ages: 24,
   ids: [1, 2, 3] ,
    greet() {
      console.log('greet')
  }
};

// let personInfo: Person2 = {
//   name: 'Danile',
//   ages: 24,
// };

// console.log(personInfo);

interface 繼承和類的實(shí)現(xiàn)

// interface 繼承
interface PersonInterface {
  name: string,
  ages: number, // :號摊趾,是必傳
  sex?: string, // 币狠?:,是非必傳
  readonly salary: number, // 只讀不能修改,  personInfo.salary = 1000(會報(bào)錯(cuò))
  [propName: string]: any, // 給任何名字
  greet(): void,
}

interface StudentInterface {
  id: number,
  course: string,
}
class People implements PersonInterface, StudentInterface{
  name: string = 'Danile';
  ages: number = 22;
  salary: number = 8000;
  id: number = 404;
  course: string = 'ts is good';
  greet() {
    console.log('hello world');
    
  }
}

// **----------------------** // 
// interface 的繼承(接口繼承接口)
interface Employee extends PersonInterface {
  work: string,
}

const employee: Employee = {
  name: 'Danile_001',
  ages: 10,
  salary: 10000,
  work: '前端研發(fā)',
  greet() {
    console.log('hello kris');
  }
}

console.log(employee);

(十)范型的使用,以及場景

// TypeScript 泛型(Generic)

// 在函數(shù)中使用泛型
// function identify<T>(arg: T): T {
//   return arg;
// }

// 可以明確指定類型
console.log(identify<string>('string'));
// console.log(identify<string>(25)); // 會報(bào)錯(cuò)

// **----------------------** // 

// 交給ts推斷類型
console.log(identify(25));

// 在接口中使用泛型
interface GenericIdentify{
  <T>(arg: T): T,
}
function identify<T>(arg: T): T {
  return arg;
}

let myIdentify: GenericIdentify = identify;

// 可以明確制定類型
console.log(myIdentify<string>('my-identify'));

// 交給ts推斷類型
console.log(myIdentify(20));

// **----------------------** // 
// 為泛型添加約束
function getLength<T extends { length: number }>(obj:T):any {
  return obj.length;
}

// 這是給泛型添加約束
// function getLength<T extends number>(obj:T):any {
//   return obj.length;
// }

const obj = {
  name: 'Danile',
  ages: 18,
  length: 10,
}

// const obj = 2000000;
console.log(getLength(obj));

// **----------------------** // 
// 泛型的應(yīng)用 -- class
class CountNumber<T extends number> {
  number1: T;
  number2: T;

  constructor(num1: T, num2: T) {
    this.number1 = num1;
    this.number2 = num2;
  }

  calcalate(): number {
    // 前面加上 + 號是ts去運(yùn)算
    return +this.number1 * +this.number2;
  }
}

const countNumber = new CountNumber<number>(10, 20);
console.log(countNumber.calcalate());

對于范型可能用到的項(xiàng)目中場景

  • 登錄用戶名砾层,可能是手機(jī)號(number)总寻,可能是名字(string)。這樣為了可復(fù)用性更高梢为,則可以考慮用范型
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末渐行,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子铸董,更是在濱河造成了極大的恐慌祟印,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粟害,死亡現(xiàn)場離奇詭異蕴忆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)悲幅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門套鹅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人汰具,你說我怎么就攤上這事卓鹿。” “怎么了留荔?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵吟孙,是天一觀的道長。 經(jīng)常有香客問我聚蝶,道長杰妓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任碘勉,我火速辦了婚禮巷挥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘验靡。我一直安慰自己倍宾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布晴叨。 她就那樣靜靜地躺著凿宾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兼蕊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天件蚕,我揣著相機(jī)與錄音孙技,去河邊找鬼产禾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛牵啦,可吹牛的內(nèi)容都是我干的亚情。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼哈雏,長吁一口氣:“原來是場噩夢啊……” “哼楞件!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起裳瘪,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤土浸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后彭羹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體黄伊,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年派殷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了还最。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡毡惜,死狀恐怖拓轻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情经伙,我是刑警寧澤悦即,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站橱乱,受9級特大地震影響辜梳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泳叠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一作瞄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧危纫,春花似錦宗挥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至螃征,卻和暖如春搪桂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工踢械, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酗电,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓内列,卻偏偏與公主長得像撵术,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子话瞧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容