TypeScript 高級(jí)(一)

類(lèi)型推斷

基于賦值表達(dá)式推斷類(lèi)型的能力稱(chēng)之為“類(lèi)型推斷”。

在 TypeScript 中螃概,具有初始化值的變量矫夯、有默認(rèn)值的函數(shù)參數(shù)、函數(shù)返回值的類(lèi)型都可以根據(jù)上下文推斷出來(lái)吊洼。比如能根據(jù) return 語(yǔ)句推斷函數(shù)返回的類(lèi)型训貌。

let str = 'hello' // string
let num = 2 // number
const bar = 'bar' //  'bar' 類(lèi)型

// 推斷返回值類(lèi)型為 number
function add(a: number, b: number) {
  return a + b
}

上下文推斷

通過(guò)變量所在的上下文環(huán)境推斷變量的類(lèi)型。

type Add = (a: number, b: number) => number
const add: Add = (a, b) => {
  return a + b
}
// 推斷出 a, b, 函數(shù)返回值都是 number 類(lèi)型

字面量類(lèi)型

在 TypeScript 中冒窍,字面量不僅可以表示值递沪,還可以表示類(lèi)型,即所謂的字面量類(lèi)型综液。

目前款慨,TypeScript 支持 3 種字面量類(lèi)型:字符串字面量類(lèi)型、數(shù)字字面量類(lèi)型谬莹、布爾字面量類(lèi)型檩奠,對(duì)應(yīng)的字符串字面量、數(shù)字字面量附帽、布爾字面量分別擁有與其值一樣的字面量類(lèi)型埠戳,示例如下:

let num: 3 = 3
let bool: true = true
let str: 'xiaomi' = 'xiaomi'

字面量類(lèi)型是集合類(lèi)型的子類(lèi)型,它是集合類(lèi)型的一種更具體的表達(dá)蕉扮。

let specifiedStr: 'this is string' = 'this is string'
let str: string = 'any string'
specifiedStr = str // ts(2322) 類(lèi)型 '"string"' 不能賦值給類(lèi)型 'this is string'
str = specifiedStr // ok

實(shí)際上整胃,定義單個(gè)的字面量類(lèi)型并沒(méi)有太大的用處,真正的應(yīng)用場(chǎng)景是可以把多個(gè)字面量類(lèi)型組合成一個(gè)聯(lián)合類(lèi)型喳钟,用于描述擁有明確成員的集合爪模。

type Direction = 'up' | 'down'

通過(guò)使用字面量類(lèi)型組合的聯(lián)合類(lèi)型,可以限制函數(shù)的參數(shù)為指定的字面量類(lèi)型集合荚藻,然后編譯器會(huì)檢查參數(shù)是否是指定的字面量類(lèi)型集合里的成員屋灌。因此,相較于使用 string 類(lèi)型应狱,使用字面量類(lèi)型(組合的聯(lián)合類(lèi)型)可以將函數(shù)的參數(shù)限定為更具體的類(lèi)型缤骨。不僅提升程序的可讀性,還保證了函數(shù)的參數(shù)類(lèi)型橘茉。

類(lèi)型拓寬

Literal Widening(字面量類(lèi)型拓寬)

所有通過(guò) let 或 var 定義的變量、函數(shù)的形參写半、對(duì)象的非只讀屬性,如果滿足指定了初始值且未顯式添加類(lèi)型注解的條件尉咕,那么它們推斷出來(lái)的類(lèi)型就是指定的初始值字面量類(lèi)型拓寬后的類(lèi)型叠蝇,就是字面量類(lèi)型拓寬。

let str = 'this is string' // 類(lèi)型是 string
let strFun = (str = 'this is string') => str // 類(lèi)型是 (str?: string) => string;
const specifiedStr = 'this is string' // 類(lèi)型是 'this is string'
let str2 = specifiedStr // 類(lèi)型是 'string'
let strFun2 = (str = specifiedStr) => str // 類(lèi)型是 (str?: string) => string;

基于字面量類(lèi)型拓寬的條件年缎,可以通過(guò)如下所示代碼添加顯示類(lèi)型注解控制類(lèi)型拓寬行為悔捶。

const specifiedStr: 'this is string' = 'this is string' // 類(lèi)型是 '"this is string"'
let str2 = specifiedStr // 即便使用 let 定義,類(lèi)型是 'this is string'

除了字面量類(lèi)型拓寬之外单芜,TypeScript 對(duì)某些特定類(lèi)型值也有類(lèi)似 "Type Widening" (類(lèi)型拓寬)的設(shè)計(jì)蜕该。

比如對(duì) null 和 undefined 的類(lèi)型進(jìn)行拓寬,通過(guò) let洲鸠、var 定義的變量如果滿足未顯式聲明類(lèi)型注解且被賦予了 null 或 undefined 值堂淡,則推斷出這些變量的類(lèi)型是 any。

let x = null // 類(lèi)型拓寬成 any
let y = undefined // 類(lèi)型拓寬成 any

Type Narrowing (類(lèi)型縮邪峭蟆)

在 TypeScript 中绢淀,可以通過(guò)某些操作將變量的類(lèi)型由一個(gè)較為寬泛的集合縮小到相對(duì)較小、較明確的集合瘾腰,這就是類(lèi)型縮小更啄。

比如,使用類(lèi)型守衛(wèi)將形參的類(lèi)型從 any 縮小到明確的類(lèi)型:

const func = (foo: any) => {
  if (typeof foo === 'string') {
    return foo // string
  } else if (typeof foo === 'number') {
    return foo // number
  }
  return null
}

還可以使用類(lèi)型守衛(wèi)將聯(lián)合類(lèi)型縮小到明確的子類(lèi)型:

const func = (foo: string | number) => {
  if (typeof foo === 'string') {
    return foo // string
  } else {
    return foo // number
  }
}

也可以通過(guò)字面量類(lèi)型等值判斷(===)或其他控制流語(yǔ)句(包括但不限于 if居灯、三目運(yùn)算符祭务、switch 分支)將聯(lián)合類(lèi)型收斂為更具體的類(lèi)型,如下代碼所示:

type Color = 'green' | 'red' | 'gray'

const getStatus = (status: Color) => {
  if (status === 'green') return status
  if (status === 'red') return status
  if (status === 'gray') return status
}

大致總結(jié):

let 聲明的簡(jiǎn)單類(lèi)型字面量會(huì)拓寬類(lèi)型怪嫌,const 聲明的簡(jiǎn)單類(lèi)型字面量會(huì)收窄义锥,const 聲明的對(duì)象變量會(huì)自動(dòng)推斷對(duì)應(yīng)的類(lèi)型,可以用 as const 收窄岩灭,讓每一個(gè) key 都是固定類(lèi)型(只讀【readonly】的值)

類(lèi)型謂詞(is)

TypeScript 中拌倍,函數(shù)還支持另外一種特殊的類(lèi)型描述:

function isString(s): s is string {
  // 類(lèi)型謂詞
  return typeof s === 'string'
}

function isNumber(n: number) {
  return typeof n === 'number'
}

function operator(x: unknown) {
  if (isString(x)) {
    // ok x 類(lèi)型縮小為 string
  }

  if (isNumber(x)) {
    // ts(2345) unknown 不能賦值給 number
  }
}

分布式有條件類(lèi)型

有條件的類(lèi)型會(huì)以一個(gè)條件表達(dá)式進(jìn)行類(lèi)型關(guān)系檢測(cè),從而在兩種類(lèi)型中選擇其一噪径,使用關(guān)鍵字 extends 配合三目運(yùn)算符:

T extends U ? X : Y

如果 extends 前面是簡(jiǎn)單的條件判斷柱恤,則直接判斷前面的類(lèi)型是否可分配給后面的類(lèi)型。

若 extends 前面的類(lèi)型是泛型找爱,且泛型傳入的是聯(lián)合類(lèi)型時(shí)梗顺,則會(huì)依次判斷該聯(lián)合類(lèi)型的所有子類(lèi)型是否可分配給 extends 后面的類(lèi)型(是一個(gè)分發(fā)的過(guò)程)。

即 T extends U ? X : Y车摄,若 T 的類(lèi)型為 A | B | C寺谤,則會(huì)被解析為(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)仑鸥。

// type A1 = 1
type A1 = 'x' extends 'x' ? 1 : 2

// type A2 = 2
type A2 = 'x' | 'y' extends 'x' ? 1 : 2

// type A3 = 1 | 2
type P<T> = T extends 'x' ? 1 : 2
type A3 = P<'x' | 'y'>

type StrOrNum<T> = T extends string ? T : number
type Str = StrOrNum<string>

// null undefined
type Str<T> = T extends null | undefined ? T : never
type Strs = StrNull<string> // never

type StrNull<T> = T extends string | null | undefined ? T : never
type Strs = StrNull<string | number> // string | number

如果用于簡(jiǎn)單的條件判斷,則是直接判斷前面的類(lèi)型是否可分配給后面的類(lèi)型

const 斷言

interface Info {
  readonly name: string
  readonly age: number
}

const info: Info = {
  name: 'hack',
  age: 23
}
// info.age = 4 // Error: ts(2540) age 為只讀屬性

// 等價(jià)于

// 使用 const 斷言
const obj = {
  name: 'jack',
  age: 34
} as const
obj.age = 5 // Error: ts(2540) age 為只讀屬性

還可以將數(shù)組轉(zhuǎn)成 readonly 元組

const arr = ['str', 12] as const
arr[1] = 55 // 無(wú)法為“1”賦值变屁,因?yàn)樗侵蛔x屬性眼俊。ts(2540)

typeof 操作符

typeof 操作符用來(lái)獲取一個(gè)變量或?qū)ο蟮念?lèi)型。也就是說(shuō) TS 對(duì) typeof 操作符做了擴(kuò)展:

type Person = {
  name: string
  age: number
}

const person: Person = {
  name: 'xiaomi',
  age: 18
}

type Human = typeof person
// type Human = {
//   name: string
//   age: number
// }

keyof

對(duì)于任何類(lèi)型 T粟关,keyof T 的結(jié)果為該類(lèi)型上所有公共屬性名的字符串或數(shù)字的組成的聯(lián)合類(lèi)型疮胖。

type Point = { x: number; 1: number }
type Keys = keyof Point
/**
  Keys 的類(lèi)型為
  type Keys = 'x' | 1
 */

如果該類(lèi)型具有 string 或 number 索引簽名,keyof 則將返回這些類(lèi)型:

type Arrayish = { [n: number]: unknown }
type A = keyof Arrayish
// type A = number

type Mapish = { [k: string]: boolean }
type M = keyof Mapish
// type M = string | number

M 類(lèi)型是 string | number闷板,是因?yàn)?JavaScript 對(duì)象鍵始終會(huì)強(qiáng)制轉(zhuǎn)換為字符串澎灸,因此 obj[0] === obj["0"]

根據(jù) TS 中對(duì)象的值或鍵創(chuàng)建聯(lián)合類(lèi)型

從對(duì)象的值或鍵創(chuàng)建聯(lián)合類(lèi)型:

  1. as const 將對(duì)象的屬性設(shè)置為readonly
  2. 用 `keyof typeof1 獲取對(duì)象中鍵的類(lèi)型
  3. 使用鍵來(lái)獲取值的并集
// ??? const obj: {readonly name: "Bobby Hadz"; readonly country: "Chile";}
const obj = {
  name: 'Bobby Hadz',
  country: 'Chile',
} as const;

// ??? type UValues = "Bobby Hadz" | "Chile"
type UValues = (typeof obj)[keyof typeof obj];

// ??? type UKeys = "name" | "country"
type UKeys = keyof typeof obj;

  1. 使用as const聲明對(duì)象是一個(gè)只讀的
  2. 使用typeof 獲取對(duì)象的類(lèi)型
  3. 使用keyof typeof 獲取對(duì)象key的聯(lián)合

T[K] 索引訪問(wèn)操作符

T[keyof K]的方式,獲取到的是 T 中的 key 且同時(shí)存在于 K 時(shí)的類(lèi)型組成的聯(lián)合類(lèi)型蛔垢。

如果[]中的 key 有不存在 T 中击孩,則是 any迫悠;因?yàn)?TS 也不知道該 key 最終是什么類(lèi)型鹏漆,所以是 any;且也會(huì)報(bào)錯(cuò)创泄。

interface Eg {
  name: string
  readonly age: number
}
// string
type V1 = Eg['name']
// string | number
type V2 = Eg['name' | 'age']
// any
type V3 = Eg['name' | 'age2222'] // Error
// string | number
type V4 = Eg[keyof Eg1]

映射類(lèi)型

typeScript 提供了從舊類(lèi)型中創(chuàng)建新類(lèi)型的一種方式 — 映射類(lèi)型艺玲。 在映射類(lèi)型里,新類(lèi)型以相同的形式去轉(zhuǎn)換舊類(lèi)型里每個(gè)屬性鞠抑。

需要使用關(guān)鍵字in

interface Ra {
  name: string
  age: number
}

type ReadonlyRa<T> = {
  readonly [K in keyof T]: T[K]
}

const ra: ReadonlyRa<Rabbit> = {
  name: 'jack',
  age: 3
}

! 非空斷言操作符

x! 將從 x 值域中排除 nullundefined饭聚。比如給某一個(gè)元素綁定點(diǎn)擊事件

// const ele: HTMLElement = document.getElementById('#app')

// 因?yàn)閑le 可能的值為 null 或 DOM節(jié)點(diǎn)。但是我們確定 ele 一定不為null搁拙,則通過(guò)添加 `!`非空斷言運(yùn)算符

const ele: HTMLElement = document.getElementById('#app')!

ele.addEventListener('click', (e: Event) => {
  //...
})

?? 空值合并運(yùn)算符

|| 或 運(yùn)算符是左側(cè)為 falsy 時(shí)秒梳,返回右側(cè)值。

null || 3 // 3
undefined || 3 // 3
false || 3 // 3
'' || 3 // 3
;-0 || 3 // 3
0 || 3 // 3
0n || 3 // 3
NaN || 3 // 3

?? 運(yùn)算符是只有左側(cè)的值為 null 或 undefined 時(shí)箕速,才返回右側(cè)的操作數(shù)酪碘,否則返回左側(cè)的值。

null ?? 3 // 3
undefined ?? 3 // 3
false ?? 3 // false

注意:不能與 &&|| 操作符共用

空值合并運(yùn)算符 ?? 不能直接與 &&|| 操作符組合使用盐茎。這種情況下會(huì)拋出 SyntaxError兴垦。

// '||' and '??' operations cannot be mixed without parentheses.(5076)
null || undefined ?? 'foo' // raises a SyntaxError

// '&&' and '??' operations cannot be mixed without parentheses.(5076)
true && undefined ?? 'foo' // raises a SyntaxError

但當(dāng)使用括號(hào)來(lái)顯式表明優(yōu)先級(jí)時(shí)是可行的,比如:

;(null || undefined) ?? 'foo' // 'foo'

內(nèi)置工具類(lèi)型

聯(lián)合類(lèi)型

Exclude<T, U>

Exclude<T, U> 提取存在于 T字柠,但不存在于 U 的類(lèi)型組成的聯(lián)合類(lèi)型探越,通俗的說(shuō):從聯(lián)合類(lèi)型中去除指定的類(lèi)型。

type Keys = Exclude<'key1' | 'key2', 'key2'>
// type Keys = 'key1'

實(shí)現(xiàn):

type Exclude<T, U> = T extends U ? never : T

never 表示一個(gè)不存在的類(lèi)型窑业,而且與其他類(lèi)型聯(lián)合后是沒(méi)有 never 的

Extract<T, U>

Extract<T, U> 提取聯(lián)合類(lèi)型 T 和聯(lián)合類(lèi)型 U 的所有交集钦幔。通俗地說(shuō):從聯(lián)合類(lèi)型中提取指定的類(lèi)型。

type Keys = Extract<'key1' | 'key2', 'key1'>
// type Keys = 'key1'

實(shí)現(xiàn):

type Extract<T, U> = T extends U ? T : never

NonNullable

NonNullable 的作用是從聯(lián)合類(lèi)型中去除 null 或者 undefined 的類(lèi)型常柄。

type T = NonNullable<string | number | undefined | null> // => string | number

實(shí)現(xiàn):

type NonNullable<T> = Exclude<T, null | undefined>
// 或者
type NonNullable<T> = T extends null | undefined ? never : T

Record

Record<K, T> 用來(lái)構(gòu)造一個(gè)類(lèi)型节槐,屬性為聯(lián)合類(lèi)型中的每個(gè)子類(lèi)型搀庶,屬性類(lèi)型為 T。

type Eg = Record<'a' | 'b', string>
/**
  type Eg = {
    a: string
    b: string
  }
/*

實(shí)現(xiàn):

type Record<K extends keyof any, T> = {
  [P in K]: T
}

注意:keyof any 得到的是 string | number | symbol铜异,原因在于 key 的類(lèi)型只能為 string | number | symbol

操作接口類(lèi)型

interface Person {
  name: string
  age?: number
  weight?: number
}

Partial<T>

將類(lèi)型 T 所有屬性設(shè)置成可選的

type PartialPerson = Partial<Person>
// 相當(dāng)于
interface PartialPerson {
  name?: string
  age?: number
  weight?: number
}

實(shí)現(xiàn):

type Partial<T> = {
  [P in keyof T]?: T[P]
}

將指定的 key 設(shè)置成可選的

type PratialOptionalPerson = PratialOptional<Person, 'name'>
//相當(dāng)于
interface PratialOptionalPerson {
  name?: string
}

實(shí)現(xiàn):

type PratialOptional<T, K extends keyof T> = {
  [P in K]?: T[K]
}

Required

將給定類(lèi)型的所有屬性變?yōu)楸剡x項(xiàng)

interface Person {
  name: string
  age?: number
  weight?: number
}

type RequiredPerson = Required<Person>
// 相當(dāng)于
interface RequiredPerson {
  name: string
  age: number
  weight: number
}

Readonly

將類(lèi)型 T 的所有屬性設(shè)置成只讀的

type ReadonlyPerson = Readonly<Person>
// 相當(dāng)于
interface ReadonlyPerson {
  readonly name: string
  readonly age?: number
  readonly weight?: number
}

實(shí)現(xiàn):

type Readonly<T> = {
  readonly [P in keyof T]: T[P]
}

將指定的 key 設(shè)置成只讀的:

type ReadonlyOptional<T, K extends keyof T> = {
  readonly [P in K]: T[P]
}

Pick

選取一組屬性哥倔,組成新的類(lèi)型

type NewPerson = Pick<Person, 'name' | 'age'>
// 相當(dāng)于
interface NewPerson {
  name: string
  age?: number
}

實(shí)現(xiàn):

type Pick<T, K extends keyof T> = {
  [P in K]: T[P]
}

Omit<T, K>

與 Pick 相反,Omit 是去除指定的屬性之后返回的新類(lèi)型

type NewPerson = Omit<Person, 'weight'>
// 相當(dāng)于
interface NewPerson {
  name: string
  age?: number
}

實(shí)現(xiàn):

  • 方式 1
type Omit = Pick<T, Exclude<keyof T, K>>
  • 方式 2
type Omit<T, K extends keyof any> = {
  [P in Exclude<keyof T, K>]: T[P]
}

以上操作接口的工具類(lèi)型都使用了映射類(lèi)型揍庄。通過(guò)映射類(lèi)型咆蒿,可以對(duì)原類(lèi)型的屬性進(jìn)行重新映射組成新的的類(lèi)型。

同態(tài)和非同態(tài)
  • Partial蚂子、Readonly 和 Pick 都屬于同態(tài)的沃测,也就是其實(shí)現(xiàn)需要輸入類(lèi)型 T 來(lái)拷貝屬性,因此屬性修飾符(readonly食茎、?)都會(huì)被拷貝
type AP = Pick<{ readonly a?: string; b: number }, 'a'>

/**
  type AP = {
    readonly a?: string | undefined
  }
 */

以上可以看出屬性修飾符 readonly 和 ? 都被拷貝了蒂破。

  • Record 是非同態(tài)的,不需要拷貝屬性别渔,因此不會(huì)拷貝屬性修飾符

為什么 Pick 拷貝了屬性附迷,而 Record 沒(méi)有拷貝?

因?yàn)?Pick 的實(shí)現(xiàn)中哎媚,P in K(本質(zhì)是 P in keyof T)喇伯,T 為輸入的類(lèi)型,而 keyof T 則遍歷了輸入類(lèi)型拨与;而 Record 的實(shí)現(xiàn)中稻据,并沒(méi)有遍歷所有輸入的類(lèi)型,K 只是約束為 keyof any 的子類(lèi)型即可买喧。
Pick捻悯、Partial、readonly 這幾個(gè)類(lèi)型工具淤毛,無(wú)一例外今缚,都是使用到了 keyof T 來(lái)輔助拷貝傳入類(lèi)型的屬性。

函數(shù)類(lèi)型

Parameters

獲取函數(shù)的參數(shù)類(lèi)型钱床,將每個(gè)參數(shù)類(lèi)型放在一個(gè)元組中

type T0 = Parameters<() => void> // []

type T1 = Parameters<(x: number, y?: string) => void> // [x: number, y?: string]

實(shí)現(xiàn):

type Parameters<T extends (...args: any) => any> = T extends (
  ...args: infer P
) => any
  ? P
  : never

ReturnType

用來(lái)獲取函數(shù)的返回類(lèi)型

type T0 = ReturnType<() => void> // => void
type T1 = ReturnType<() => string> // => string

實(shí)現(xiàn):

type ReturnType<T extends (...args: any) => any> = T extends (
  ...args: any
) => infer R
  ? R
  : any

ThisParameterType

用來(lái)獲取函數(shù)的 this 參數(shù)類(lèi)型

type T = ThisParameterType<(this: Number, x: number) => void> // Number

實(shí)現(xiàn):

type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any
  ? U
  : unknown

OmitThisParameter

用來(lái)去除函數(shù)類(lèi)型中的 this 類(lèi)型荚斯。如果傳入的函數(shù)類(lèi)型沒(méi)有顯式聲明 this 類(lèi)型,那么返回的仍是原來(lái)的函數(shù)類(lèi)型

type T = OmitThisParameter<(this: Number, x: number) => string> // (x: number) => string

實(shí)現(xiàn):

type OmitThisParameter<T> = unknown extends ThisParameterType<T>
  ? T
  : T extends (...args: infer A) => infer R
  ? (...args: A) => R
  : T

字符串類(lèi)型

Uppercase

字符串字面量轉(zhuǎn)換成大寫(xiě)字母

type T = Uppercase<'Hello'> // => 'HELLO'

Lowercase

字符串字面量轉(zhuǎn)換成小寫(xiě)字母

type T = Lowercase<'HElO'> // => 'hello'

Capitalize

字符串的第一個(gè)字母轉(zhuǎn)為大寫(xiě)字母

type T = Capitalize<'hello'> // => 'Hello'

Uncapitalize

字符串第一個(gè)字母轉(zhuǎn)成小寫(xiě)

type T = Uncapitalize<'Hello'> // => 'hello'
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末查牌,一起剝皮案震驚了整個(gè)濱河市事期,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纸颜,老刑警劉巖兽泣,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異胁孙,居然都是意外死亡唠倦,警方通過(guò)查閱死者的電腦和手機(jī)称鳞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)稠鼻,“玉大人冈止,你說(shuō)我怎么就攤上這事『虺荩” “怎么了熙暴?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)慌盯。 經(jīng)常有香客問(wèn)我周霉,道長(zhǎng),這世上最難降的妖魔是什么亚皂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任俱箱,我火速辦了婚禮,結(jié)果婚禮上灭必,老公的妹妹穿的比我還像新娘狞谱。我一直安慰自己,他們只是感情好厂财,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布芋簿。 她就那樣靜靜地躺著峡懈,像睡著了一般璃饱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肪康,一...
    開(kāi)封第一講書(shū)人閱讀 51,541評(píng)論 1 305
  • 那天荚恶,我揣著相機(jī)與錄音,去河邊找鬼磷支。 笑死谒撼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雾狈。 我是一名探鬼主播廓潜,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼善榛!你這毒婦竟也來(lái)了辩蛋?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤移盆,失蹤者是張志新(化名)和其女友劉穎悼院,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體咒循,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡据途,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年绞愚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颖医。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡位衩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出熔萧,到底是詐尸還是另有隱情蚂四,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布哪痰,位于F島的核電站遂赠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏晌杰。R本人自食惡果不足惜跷睦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肋演。 院中可真熱鬧抑诸,春花似錦、人聲如沸爹殊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)梗夸。三九已至层玲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間反症,已是汗流浹背辛块。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铅碍,地道東北人润绵。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像胞谈,于是被迫代替她去往敵國(guó)和親尘盼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

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

  • 一烦绳、交叉類(lèi)型 交叉類(lèi)型將多個(gè)類(lèi)型合并為一個(gè)新的類(lèi)型卿捎,新的具有所有參與合并的類(lèi)型的特性,本質(zhì)上是一種并的操作爵嗅。形式如...
    kuxingseng686閱讀 530評(píng)論 0 0
  • 交叉類(lèi)型 交叉類(lèi)型將多個(gè)類(lèi)型合并為一個(gè)類(lèi)型娇澎,相當(dāng)于新類(lèi)型具有這多個(gè)類(lèi)型的所有特性,相當(dāng)于是一種并的操作睹晒,通常在使用...
    這個(gè)前端不太冷閱讀 667評(píng)論 0 0
  • 映射類(lèi)型 一個(gè)常見(jiàn)的任務(wù)是將一個(gè)已知的類(lèi)型每個(gè)屬性都變?yōu)榭蛇x的: interface PersonPartial ...
    2o壹9閱讀 1,529評(píng)論 1 49
  • 首發(fā)知乎:https://zhuanlan.zhihu.com/p/438903357[https://zhuan...
    Hugo_TCCY閱讀 638評(píng)論 0 0
  • 多態(tài)的 this類(lèi)型 多態(tài)的 this類(lèi)型表示的是某個(gè)包含類(lèi)或接口的 子類(lèi)型趟庄。 這被稱(chēng)做 F-bounded多態(tài)性...
    2o壹9閱讀 521評(píng)論 1 50