精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

以淘寶店鋪為例,談談 TypeScript ESLint 規則集考量

開發 前端
通過這篇文章,你會了解到在制定規則時我們考慮的是什么,對于 TypeScript 代碼進行約束的思考,以及如何在自己的團隊內推廣這一套規則。

前言

ESLint 在項目中已經是大家見慣不慣的存在,你可能很厭煩動不動跳出來的 ESLint 報錯,也可能很享受經過統一校驗的工工整整的代碼,無論如何,我的意見是,在稍微正式點的項目中都要有 ESLint 的存在,無論是直接使用簡單的 recommend 配置如 extends: ['eslint: recommend'],還是精心研究了一整套適用于自己的規則集,Lint 工具的最大幫助就是保持語法統一,至少項目中的所有 JavaScript 文件應使用統一的單雙引號、分號、縮進等風格(僅靠編輯器并不能保證)。

其次,Lint 幫助你的代碼更加簡潔、有效,如不允許未使用的變量、JSX/TSX 中使用簡寫的 true 屬性( 而不是 )等、還有一點值得一提,ESLint 并不會一直嘗試去簡化你的代碼,在很多情況下它會要求你寫更多代碼來換取可讀性和安全性的提升,尤其是在 TypeScript 場景下,explicit-module-boundary-types 規則會要求你為函數與類方法顯式的聲明其返回值,switch-exhaustiveness-check 規則會要求你處理聯合類型變量的所有類型分支。

本文來自于我在所在團隊(淘寶店鋪)內部制定、落地、推廣 ESLint 規則集的收獲,將會簡要的介紹一批我認為在 TypeScript 分享中非常有必要的規則,通過這篇文章,你會了解到在制定規則時我們考慮的是什么,對于 TypeScript 代碼進行約束的思考,以及如何在自己的團隊內推廣這一套規則。

另外,淘系技術部前端架構團隊正在淘系內推廣 AppLint,準備將 ESLint 推廣到整個淘系前端作為 CI/CD 的卡口之一,歡迎集團的同學了解并試用。

P.S. 我參與的 QCon+ 專題:TypeScript 在中大型項目中的落地實踐[1] 中,淘寶店鋪 TypeScript 研發規約落地[2] 這一課程包括了我們團隊從 JavaScript 遷移到 TypeScript 以及落地完整的研發規約經驗,歡迎來聽~

基礎約束

為了適應讀者可能有的不同的約束嚴格程度,這里將規則拆分為基礎約束與嚴格約束部分,基礎約束的規則以語法統一(包括實際代碼與類型部分)為主,推薦所有人在所有項目中使用,即使是個人項目——說實在的,都寫 TypeScript 了,還在意這小小的 Lint 規則?而嚴格約束部分更關注類型以及 ECMAScript、TypeScript 的特殊語法,適合對代碼質量要求較高的同學。這里不會給出推薦的錯誤等級,即使全部是 warn,只要你打開了,至少你也會在以后心情好的時候來修對吧?(對吧?)

array-type

TypeScript 中支持使用 Array 與 T[] 的形式聲明數組類型,此規則約束項目中對這兩種數組類型的聲明。

其支持的配置:

  • 僅使用 Array 或 T[] 其中一種
  • 對于原始類型與類型別名使用 T[],對于對象類型、函數類型等使用 Array(推薦)

為什么?:對于這種效果完全一致的語法,我們需要的只是確定一個規范然后在所有地方使用這一規范。實際上,這一類規則(還有后面的類型斷言語法)就類似于單引號/雙引號,加不加分號這種基礎規則,如果你不能接受上一行代碼單引號這一行代碼雙引號,那么也沒理由能接受這里一個 Array 那里一個 number[],另外,我個人推薦統一使用 []。

await-thenable

只允許對異步函數、Promise、PromiseLike 使用 await 調用

為什么:避免無意義的 await 調用。

ban-ts-comment

禁止 @ts- 指令的使用,或者允許其在提供了說明的情況下被使用,如:

  1. // @ts-expect-error 這里的類型太復雜,日后補上 
  2. // @ts-nocheck 未完成遷移的文件 

此規則推薦與 prefer-ts-expect-error 搭配使用,詳見下方。

為什么:如果說亂寫 any 叫 AnyScript,那么亂寫 @ts-ignore 就可以叫 IgnoreScript 了。

ban-types

禁止部分值被作為類型標注,此規則能夠對每一種被禁用的類型提供特定的說明來在觸發此規則報錯時給到良好的提示,場景如禁用 {}、Function、object 這一類被作為類型標注,

為什么?使用 {} 會讓你寸步難行:類型 {} 上不存在屬性 'foo',所以用了 {} 你大概率在下面還需要類型斷言回去或者變 any,使用 object Function 毫無意義。

  • 對于未知的對象類型,應使用 Record
  • 對于函數類型,應使用入參、返回值被標注出來的具體類型:type SomeFunc = (arg1: string) => void ,或在未知的場景下使用 type SomeFunc = (...args: any[]) => any。

consistent-type-assertions

TypeScript 支持通過 as 與 <> 兩種不同的語法進行類型斷言,如:

  1. const foo = {} as Foo; 
  2. const foo = <Foo>{}; 
  3. // 類似的還有常量斷言 
  4. const foo = <const>[1, 2]; 
  5. const foo = [1, 2, 3] as const; 

這一規則約束使用統一的類型斷言語法,我個人一般在 Tsx 中使用 as ,在其他時候盡可能的使用 <>,原因則是 <> 更加簡潔。

為什么:類似于 array-type,做語法統一,但需要注意的是在 Tsx 項目中使用 <> 斷言會導致報錯,因為不像泛型可以通過 來顯式告知編譯器這里是泛型語法而非組件。

explicit-module-boundary-types

函數與類方法的返回值需要被顯式的指定,而不是依賴類型推導,如:

  1. const foo = (): Foo => {}; 

為什么:通過顯式指定來直觀的區分函數的功能,如副作用等,同時顯式指定的函數返回值也能在一定程度上提升 TypeScript Compiler 性能。

no-extra-non-null-assertion

不允許額外的重復非空斷言:

  1. // x 
  2. function foo(bar: number | undefined) { 
  3.   const bar: number = bar!!!; 

為什么:額,why not?

prefer-for-of

在你使用 for 循環遍歷數組時,如果索引僅僅用來訪問數組成員,則應該替換為 for...of。

為什么:如果不是為了兼容性場景,在這種場景下的確沒有必要使用 for 循環。

prefer-nullish-coalescing && prefer-optional-chain

使用 ?? 而不是 ||,使用 a?.b 而不是 a && a.b。

為什么:邏輯或 || 會將 0 與 "" 視為 false 而導致錯誤的應用默認值,而可選鏈相比于邏輯與 && 則能夠帶來更簡潔的語法(尤其是在屬性訪問嵌套多層,或值來自于一個函數時,如 document.querySelector),以及與 ?? 更好的協作:const foo = a?.b?.c?.d ?? 'default';。

no-empty-interface

不允許定義空的接口,可配置為允許單繼承下的空接口:

  1. // x 
  2. interface Foo {} 
  3.  
  4. // √ 
  5. interface Foo extends Bar {} 

為什么:沒有父類型的空接口實際上就等于 {},雖然我不確定你使用它是為了什么,但我能告訴你這是不對的。而單繼承的空接口場景則是較多的,如先確定下繼承關系再在后續添加成員。

no-explicit-any

不允許顯式的 any。

實際上這條規則只被設置為 warn 等級,因為真的做到一個 any 不用或是全部替換成 unknown + 類型斷言 的形式成本都非常高。

推薦配合 tsconfig 的 --noImplicitAny (檢查隱式 any)來盡可能的保證類型的完整與覆蓋率。

no-inferrable-types

不允許不必要的類型標注,但可配置為允許類的屬性成員、函數的屬性成員進行額外標注。

  1. const foo: string = "linbudu"
  2.  
  3. class Foo { 
  4.   prop1: string = "linbudu"
  5.  
  6. function foo(a: number = 5, b: boolean = true) { 
  7.   // ... 

為什么:對于普通變量來說,與實際賦值一致的類型標注確實是沒有意義的,TypeScript 的控制流分析能很好地做到這一點,而對于函數參數與類屬性,主要是為了確保一致性,即函數的所有參數(包括重載的各個聲明)、類的所有屬性都有類型標注,而不是僅為沒有初始值的參數/屬性進行標注。

no-non-null-asserted-nullish-coalescing

不允許非空斷言與空值合并同時使用:bar! ?? tmp

為什么:冗余

no-non-null-asserted-optional-chain

不允許非空斷言與可選鏈同時使用:foo?.bar!

為什么:和上一條規則一樣屬于冗余,同時意味著你對 ! ?? ?. 的理解存在著不當之處。

no-throw-literal

不允許直接 throw 一個字符串如:throw 'err',只能拋出 Error 或基于 Error 派生類的實例,如:throw new Error('Oops!')。

為什么:拋出的 Error 實例能夠自動的收集調用棧信息,同時借助 proposal-error-cause[3] 提案還能夠跨越調用棧來附加錯誤原因傳遞上下文信息,不過,真的會有人直接拋出一個字符串嗎??

no-unnecessary-type-arguments

不允許與默認值一致的泛型參數,如:

  1. function foo<T = number>() {} 
  2. foo<number>(); 

為什么:出于代碼簡潔考慮。

no-unnecessary-type-assertion

不允許與實際值一致的類型斷言,如:const foo = 'foo' as string。

為什么:你懂的。

no-unnecessary-type-constraint

不允許與默認約束一致的泛型約束,如:interface FooAny {}。

為什么:同樣是出于簡化代碼的考慮,在 TS 3.9 版本以后,對于未指定的泛型約束,默認使用 unknown ,在這之前則是 any,知道這一點之后你就沒必要再多寫 extends unknown 了。

non-nullable-type-assertion-style

此規則要求在類型斷言僅起到去空值作用,如對于 string | undefined 類型斷言為 string時,將其替換為非空斷言 !

  1. const foo: string | undefined = "foo"
  2.  
  3. // √ 
  4. foo!; 
  5. // x 
  6. foo as string; 

為什么:當然是因為簡化代碼了!此規則的本質是檢查經過斷言后的類型子集是否僅剔除了空值部分,因此無需擔心對于多種有實際意義的類型分支的聯合類型誤判。

prefer-as-const

對于常量斷言,使用 as const 而不是 ,這一點類似于上面的 consistent-type-assertions 規則。

prefer-literal-enum-member

對于枚舉成員值,只允許使用普通字符串、數字、null、正則,而不允許變量復制、模板字符串等需要計算的操作。

為什么:雖然 TypeScript 是允許使用各種合法表達式作為枚舉成員的,但由于枚舉的編譯結果擁有自己的作用域,因此可能導致錯誤的賦值,如:

  1. const imOutside = 2; 
  2. const b = 2; 
  3. enum Foo { 
  4.   outer = imOutside, 
  5.   a = 1, 
  6.   b = a, 
  7.   c = b, 

這里 c == Foo.b == Foo.c == 1,還是 c == b == 2 ? 觀察下編譯結果:

  1. "use strict"
  2. const imOutside = 2; 
  3. const b = 2; 
  4. var Foo; 
  5. (function (Foo) { 
  6.   Foo[(Foo["outer"] = imOutside)] = "outer"
  7.   Foo[(Foo["a"] = 1)] = "a"
  8.   Foo[(Foo["b"] = 1)] = "b"
  9.   Foo[(Foo["c"] = 1)] = "c"
  10. })(Foo || (Foo = {})); 

懂伐小老弟?

prefer-ts-expect-error

使用 @ts-expect-error 而不是 @ts-ignore。

為什么:@ts-ignore 與 @ts-expect-error 二者的區別主要在于,前者是 ignore,是直接放棄了下一行的類型檢查而無論下一行是否真的有錯誤,后者則是期望下一行確實存在一個錯誤,并且會在下一行實際不存在錯誤時拋出一個錯誤。

這一類干涉代碼檢查指令的使用本就應該慎之又慎,在任何情況下都不應該被作為逃生艙門(因為它真的比 any 還好用),如果你一定要用,也要確保用的恰當。

promise-function-async

返回 Promise 的函數必須被標記為 async,此規則能夠確保函數的調用方只需要處理 try/catch 或者 rejected promise 的情況。

為什么:還用解釋嗎?

嚴格約束

no-unnecessary-boolean-literal-compare

不允許對布爾類型變量與 true / false 的 === 比較,如:

  1. declare const someCondition: boolean; 
  2. if (someCondition === true) { 

為什么:首先,記住我們是在寫 TypeScript,所以不要想著你的變量值還有可能是 null 所以需要這樣判斷,如果真的發生了,那么說明你的 TS 類型標注不對哦。而且,此規則的配置項最多允許 boolean | null 這樣的值與 true / false 進行比較,所以還是讓你的類型更精確一點吧。

consistent-type-definitions

TypeScript 支持通過 type 與 interface 聲明對象類型,此規則可將其收束到統一的聲明方式,即僅使用其中的一種。

為什么:先說我是怎么做得:在絕大部分場景下,使用 interface 來聲明對象類型,type 應當用于聲明聯合類型、函數類型、工具類型等,如:

  1. interface IFoo {} 
  2.  
  3. type Partial<T> = { 
  4.   [P in keyof T]?: T[P]; 
  5. }; 
  6.  
  7. type LiteralBool = "true" | "false"

原因主要有這么幾點:

  • 配合 naming-convention 規則(能夠用于檢查接口是否按照規范命名),我們能夠在看見 IFoo 時立刻知道它是一個 接口,看見 Bar 時立刻知道它是一個類型別名,配置:
  1.   "@typescript-eslint/naming-convention": [ 
  2.     "error"
  3.     { 
  4.       "selector""interface"
  5.       "format": ["PascalCase"], 
  6.       "custom": { 
  7.         "regex""^I[A-Z]"
  8.         "match"true 
  9.       } 
  10.     } 
  11.   ] 
  • 接口在類型編程中的作用非常局限,僅支持 extends、泛型 等簡單的能力,也應當只被用于定義確定的結構體。而 Type Alias 能夠使用除 extends 以外所有常見的映射類型、條件類型等類型編程語法。同時,“類型別名”的含義也意味著你實際上是使用它來歸類類型(聯合類型)、抽象類型(函數類型、類類型)。

method-signature-style

方法簽名的聲明方式有 method 與 property 兩種,區別如下:

  1. // method 
  2. interface T1 { 
  3.   func(arg: string): number; 
  4.  
  5. // property 
  6. interface T2 { 
  7.   func: (arg: string) => number; 

此規則將聲明方式進行約束,推薦使用第二種的 property 方式。

為什么:首先,這兩種方式被稱為 method 與 property 很明顯是因為其對應的寫法,method 方式類似于在 Class 中定義方法,而 property 則是就像定義普通的接口屬性,只不過它的值是函數類型。推薦使用 property 的最重要原因是,通過使用 屬性 + 函數值 的方式定義,作為值的函數的類型能享受到更嚴格的類型校驗( `strictFunctionTypes`[4]),此配置會使用逆變(contravariance)而非協變(covariance)的方式進行函數參數的檢查,關于協變與逆變我后續會單獨的寫一篇文章,這里暫時不做展開,如果你有興趣,可以閱讀 TypeScript 類型中的逆變協變。

consistent-type-imports

約束使用 import type {} 進行類型的導入,如:

  1. // √ 
  2. import type { CompilerOptions } from "typescript"
  3.  
  4. // x 
  5. import { CompilerOptions } from "typescript"

為什么:import type 能夠幫助你更好的組織你的項目頭部的導入結構(雖然 TypeScript 4.5 支持了類型與值的混合導入:import { foo, type Foo },但還是推薦通過拆分值導入與類型導入語句來獲得更清晰地項目結構)。值導入與類型導入在 TypeScript 中使用不同的堆空間來存放,因此無須擔心循環依賴(所以你可以父組件導入子組件,子組件導入定義在父組件中的類型這樣)。

一個簡單的、良好組織了導入語句的示例:

  1. import { useEffect } from "react"
  2.  
  3. import { Button, Dialog } from "ui"
  4. import { ChildComp } from "./child"
  5.  
  6. import { store } from "@/store"
  7. import { useCookie } from "@/hooks/useCookie"
  8. import { SOME_CONSTANTS } from "@/utils/constants"
  9.  
  10. import type { Foo } from "@/typings/foo"
  11. import type { Shared } from "@/typings/shared"
  12.  
  13. import styles from "./index.module.scss"

restrict-template-expressions

模板字符串中的計算表達式其返回值必須是字符串,此規則可以被配置為允許數字、布爾值、可能為 null 的值以及正則表達式,或者你也可以允許任意的值,但這樣就沒意思了...

為什么:在模板表達式中非字符串與數字以外的值很容易帶來潛在的問題,如:

  1. const arr = [1, 2, 3]; 
  2. const obj = { name"linbudu" }; 
  3.  
  4. // 'arr: 1,2,3' 
  5. const str1 = `arr: ${arr}`; 
  6. // 'obj: [object Object]' 
  7. const str2 = `obj: ${obj}`; 

無論哪種情況都不會是你想看到的,因為這實際上已經脫離了你的掌控。推薦在規則配置中僅開啟 allowNumber 來允許數字,而禁止掉其他的類型,你所需要做得應當是在把這個變量填入模板字符串中時進行一次具有實際邏輯的轉化。

switch-exhaustiveness-check

switch 的判定條件為 聯合類型 時,其每一個類型分支都需要被處理。如:

  1. type PossibleTypes = "linbudu" | "qiongxin" | "developer"
  2.  
  3. let value: PossibleTypes; 
  4. let result = 0; 
  5.  
  6. switch (value) { 
  7.   case "linbudu": { 
  8.     result = 1; 
  9.     break; 
  10.   } 
  11.   case "qiongxin": { 
  12.     result = 2; 
  13.     break; 
  14.   } 
  15.   case "developer": { 
  16.     result = 3; 
  17.     break; 
  18.   } 

為什么:工程項目中經常出現的,導致問題發生的原因就是有部分功能邏輯點僅通過口口相傳,只看代碼你完全不知道自己還漏了什么地方。如聯合類型變量中每一條類型分支可能都需要特殊的處理邏輯。

你也可以通過 TypeScript 中的 never 類型來實現實際代碼的檢驗:

  1. const strOrNumOrBool: string | number | boolean = false
  2.  
  3. if (typeof strOrNumOrBool === "string") { 
  4.   console.log("str!"); 
  5. else if (typeof strOrNumOrBool === "number") { 
  6.   console.log("num!"); 
  7. else if (typeof strOrNumOrBool === "boolean") { 
  8.   console.log("bool!"); 
  9. else { 
  10.   const _exhaustiveCheck: never = strOrNumOrBool; 
  11.   throw new Error(`Unknown input type: ${_exhaustiveCheck}`); 

這里通過編譯時與運行時做了兩重保障,確保為聯合類型新增類型分支時也需要被妥善的處理,你可以參考開頭的 never 類型 文章了解更多 never 相關的使用。除了聯合類型以外,你還可以通過 never 類型來確保每一個枚舉成員都需要處理。

  1. enum PossibleType { 
  2.   Foo = "Foo"
  3.   Bar = "Bar"
  4.   Baz = "Baz"
  5.  
  6. function checker(input: PossibleType) { 
  7.   switch (input) { 
  8.     case PossibleType.Foo: 
  9.       console.log("foo!"); 
  10.       break; 
  11.     case PossibleType.Bar: 
  12.       console.log("bar!"); 
  13.       break; 
  14.     case PossibleType.Baz: 
  15.       console.log("baz!"); 
  16.       break; 
  17.     default
  18.       const _exhaustiveCheck: never = input; 
  19.       break; 
  20.   } 

以上就是我們目前在使用的部分規則,還有一批規則或是涉及到高度的定制或是適用場景狹窄,這里就不做列舉了。如果你有什么想法,歡迎與我一起交流,但請注意:我不是在灌輸你一定要使用什么規則,我只是在分享我們使用的規則以及考量,因此在留言前請確認不要屬于此類觀點,感謝你的閱讀。

參考資料

[1]QCon+ 專題:TypeScript 在中大型項目中的落地實踐: https://qconplus.infoq.cn/2021/beijing2nth/track/1240

[2]淘寶店鋪 TypeScript 研發規約落地: https://qconplus.infoq.cn/2021/beijing2nth/presentation/4161

[3]proposal-error-cause: https://github.com/tc39/proposal-error-cause

[4]strictFunctionTypes: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-6.html#strict-function-types

 

責任編輯:姜華 來源: 三元同學
相關推薦

2017-11-02 14:46:18

JavaScriptTypeScript遍歷

2025-05-13 08:09:56

2021-08-02 09:50:47

Vetur源碼SMART

2017-06-30 15:33:57

大數據數據分析用戶評論

2016-12-20 12:34:46

存儲MySQL流程

2023-03-31 14:33:49

人工智能數據開發自然語言

2019-05-20 08:20:40

數據集數據可視化數據

2018-08-22 16:40:51

前端JavascriptVue

2021-05-31 08:00:00

消息隊列架構Rabbit MQ

2011-07-08 09:55:02

數據中心防震

2018-01-16 08:57:24

Nginx規則實用

2014-03-12 13:33:10

淘寶京東亞馬遜

2022-02-14 14:28:57

驅動開發鴻蒙系統

2021-04-16 08:20:00

Flink CEP直播監控

2009-03-02 16:57:34

LinuxUbuntu配置完全方案

2021-01-14 09:00:00

開發FedoraUbuntu

2015-07-01 15:39:52

Ceph云存儲NAS

2013-02-18 10:12:58

Apache服務器訪問動態網站

2015-05-07 11:24:13

DockerIT技術評價新技術

2010-09-07 10:01:47

網游服務器搭建方案
點贊
收藏

51CTO技術棧公眾號

日韩成人av网址| 中文字幕精品综合| 97视频网站入口| 公侵犯人妻一区二区三区| av成人亚洲| 亚洲午夜一区二区三区| 欧美一区二区高清在线观看| 中文字幕网址在线| 影音先锋中文字幕一区| 亚洲视频在线观看网站| 女人高潮一级片| 悠悠资源网亚洲青| 亚洲三级在线免费观看| 欧美日韩视频在线一区二区观看视频| 国产农村老头老太视频| 国产精品夜夜夜| 欧美精品在线免费观看| 微拍福利一区二区| 欧美大胆a级| 91精品视频网| 我要看一级黄色大片| 波多野结衣在线高清| 国产精品久久看| 六月婷婷久久| 午夜精品久久久久久久96蜜桃 | 久久久国产一区二区| 黄色性生活一级片| 粉嫩的18在线观看极品精品| 欧美精品在线一区二区三区| 国产肥臀一区二区福利视频| 国产www视频在线观看| 国产精品久久久久国产精品日日| 欧美日韩三区四区| 亚洲av成人精品一区二区三区在线播放| 久久国产精品第一页| 日韩av色综合| 成人免费毛片男人用品| 国产精品久久久久久久免费软件| 欧美激情18p| 高h视频免费观看| 91欧美在线| 一区二区欧美亚洲| 国产成人精品无码免费看夜聊软件| 国产精品极品| 精品久久国产老人久久综合| 欧美性猛交乱大交| 精品国产乱码久久久久久樱花| 欧美美女一区二区在线观看| 日本不卡一区在线| 男人亚洲天堂| 欧美日韩精品一区二区| 亚洲天堂2018av| 国产原创一区| 6080yy午夜一二三区久久| 9久久婷婷国产综合精品性色| 国产精品一区二区av影院萌芽| 欧美日韩性生活视频| av之家在线观看| 是的av在线| 色综合久久综合网97色综合| 黑人糟蹋人妻hd中文字幕| 超碰国产一区| 欧美综合在线视频| 日日干夜夜操s8| 亚洲18在线| 欧美一区二区三区男人的天堂| 国产999免费视频| 日韩在线观看中文字幕| 亚洲成人在线网| 三叶草欧洲码在线| 国产欧美日韩一区二区三区四区| 一区二区三区国产视频| 久久爱一区二区| 欧美91精品| 久久久久久久国产精品| www.国产色| 日韩av在线播放中文字幕| 91精品久久久久| 性生交生活影碟片| 91在线视频在线| 天天爽天天狠久久久| 乱人伦中文视频在线| 艳妇臀荡乳欲伦亚洲一区| 奇米影视亚洲色图| 校园春色亚洲色图| 91精品综合久久久久久| 欧美xxxxx少妇| 美女精品一区最新中文字幕一区二区三区 | 亚洲中国色老太| 性一交一乱一伧老太| 91一区二区在线观看| 神马影院我不卡| yellow91字幕网在线| 精品成人av一区| 不卡av免费在线| 免费观看亚洲天堂| 日韩电影免费观看中文字幕| 免费成人深夜蜜桃视频| 亚洲午夜一级| 国产免费一区二区三区香蕉精| 国产aⅴ一区二区三区| 91网页版在线| 亚洲免费视频播放| 亚洲黄色免费av| 91精品国产综合久久久蜜臀图片| 国产ts丝袜人妖系列视频| 国产精品97| 日本一欧美一欧美一亚洲视频| 99精品免费观看| 国产亚洲欧美日韩日本| 国产高清av在线播放| 日韩av在线免费| 乌克兰美女av| 精品按摩偷拍| 按摩亚洲人久久| 国产又爽又黄的视频| 国产在线不卡一区| 欧美综合77777色婷婷| 国产99re66在线视频| 欧美日韩国产综合一区二区三区| 亚洲国产第一区| 一区二区免费不卡在线| 国产精品久久久久久搜索| 特黄视频在线观看| 亚洲激情自拍视频| 视频在线观看免费高清| 日韩高清成人在线| 久久久亚洲精选| 99国产精品久久久久久久成人| 久久精品在这里| 欧美 国产 综合| 国产欧美日本一区视频| 亚洲综合中文字幕在线| 毛片在线免费| 精品动漫一区二区三区| 久久精品国产99久久99久久久| 国产乱子伦精品| 三区在线观看| 亚洲成人黄色影院| 性鲍视频在线观看| 99精品综合| 国产91精品久| 久久久久久久久久久99| **欧美日韩在线| 亚洲人成在线免费观看| 黄网在线观看视频| 成人的网站免费观看| 免费cad大片在线观看| 国产女人在线观看| 久久精品一区二区三区不卡 | 三年中国国语在线播放免费| 妖精一区二区三区精品视频| 欧美中文字幕在线播放| 手机在线观看免费av| 亚洲高清久久久| 久久久久成人精品无码中文字幕| 亚洲激情午夜| 精品一区久久久| 在线视频cao| 亚洲性日韩精品一区二区| 天干夜夜爽爽日日日日| 国产日韩影视精品| 亚洲欧美自偷自拍另类| 欧美电影免费观看高清| 亚洲一区二区三区毛片| 亚洲色图美国十次| 国产乱人伦丫前精品视频| 亚洲欧美另类在线观看| 精品不卡一区二区| 日本一区二区免费在线| 中文字幕免费高清在线| 欧美/亚洲一区| 久久成人资源| 日韩成人亚洲| 久久综合亚洲社区| 亚洲黄色小说网| 欧美日韩国产专区| 亚洲av熟女国产一区二区性色| 久久99精品国产麻豆不卡| 欧美大片免费播放| 秋霞影视一区二区三区| 国产男女猛烈无遮挡91| 欧美性受ⅹ╳╳╳黑人a性爽| 日韩成人激情视频| 一本色道久久综合熟妇| 亚洲一区二区中文在线| 人妻少妇无码精品视频区| 久久国产福利国产秒拍| 国产不卡一区二区视频| av一区二区在线播放| 91热福利电影| 欧美二三四区| 欧美日韩成人黄色| 韩国三级av在线免费观看| 欧美一级在线免费| wwwwww国产| 亚洲精品第1页| 公侵犯人妻一区二区三区| 国产在线日韩欧美| 日本一区二区黄色| 欧美粗暴jizz性欧美20| 日韩国产伦理| 国产成人一二片| 国产精品揄拍一区二区| 三级在线观看视频| 美女国内精品自产拍在线播放| 日韩精品系列| 欧美精品一区二区三| 国产精品欧美久久久久天天影视| 欧美午夜电影在线| 青青草原国产视频| 国产精品入口麻豆原神| 成人影视免费观看| 成人av电影在线网| 欧美精品色视频| 另类专区欧美蜜桃臀第一页| 毛片一区二区三区四区| 91久久黄色| 桥本有菜av在线| 亚洲精品国产欧美在线观看| 日本在线中文字幕一区| 国产在线不卡精品| 性感美女一区二区在线观看| 韩国精品久久久999| 18av在线播放| 久久久成人的性感天堂| 9色在线视频| 亚洲色图综合网| 亚洲色图欧美视频| 亚洲成人a级网| 好男人在线视频www| 欧美一级二级在线观看| 国产影视一区二区| 欧美色图天堂网| 伊人网综合在线| 欧洲国内综合视频| 日韩不卡高清视频| 在线影视一区二区三区| 欧美精品一二三四区| 欧美日韩裸体免费视频| 久久久久久久极品| 午夜视频在线观看一区二区三区| 国产性生活网站| 一区二区高清免费观看影视大全| 欧美色图一区二区| 一区二区三区精品| 伊人国产在线观看| 精品欧美国产一区二区三区| wwwxxx亚洲| 色婷婷综合久久久久中文一区二区| 日韩手机在线视频| 欧美午夜片在线观看| 亚洲图片小说视频| 正在播放亚洲一区| 精品久久在线观看| 精品国精品国产| 日韩一级免费毛片| 国产视频精品一区二区三区| 天天操天天操天天| 亚洲欧美国产一本综合首页| 国产小视频在线| 综合av色偷偷网| 成人短视频在线观看| 欧美精品福利视频| 天堂中文在线播放| 国产精品欧美日韩| 国产一区二区三区| 国产精品免费一区二区三区在线观看| 福利在线一区| 日本亚洲自拍| 影音先锋成人在线电影| 18禁裸男晨勃露j毛免费观看| 国产日韩1区| 波多野结衣xxxx| 国产a级毛片一区| jizz欧美性20| 国产精品日日摸夜夜摸av| 精品97人妻无码中文永久在线| 欧美日韩国产黄| 在线播放精品视频| 精品国产乱码久久久久久久久| 久久av少妇| 欧美黑人极品猛少妇色xxxxx| 亚洲男人av| 91色在线观看| 五月天亚洲色图| 黄瓜视频免费观看在线观看www| 在线观看不卡| 911福利视频| 91在线丨porny丨国产| 精品无码一区二区三区蜜臀| 欧美日韩日本国产| 国产精品天天操| 亚洲免费中文字幕| 亚洲无线看天堂av| 国产精品久久久久久搜索| 国产精品1luya在线播放| 日韩福利在线| 亚洲福利国产| 91网址在线观看精品| 久久久综合网站| 免费在线看黄网址| 欧美三级日韩三级| 日韩有码电影| 欧美国产精品va在线观看| 日韩制服诱惑| 久久久久久久有限公司| 欧美一区免费| 宅男噜噜噜66国产免费观看| 成人白浆超碰人人人人| 亚洲AV成人无码精电影在线| 欧美午夜丰满在线18影院| www日本在线| 日韩中文视频免费在线观看| 综合日韩av| 韩国一区二区三区美女美女秀 | 亚洲欧美一区二区三区四区| 尤物视频在线看| 91免费观看网站| 日韩高清欧美| 玩弄japan白嫩少妇hd| 成人黄色综合网站| 国产a免费视频| 欧美人狂配大交3d怪物一区| 国产中文在线| 日韩av免费在线播放| 老牛国内精品亚洲成av人片| 国产精品av免费观看| 极品少妇xxxx精品少妇| 日韩精品电影一区二区三区| 91黄色免费看| 黄网在线观看| 国产成人激情视频| 亚洲动漫精品| 午夜肉伦伦影院| 99国产欧美另类久久久精品| 国产精品suv一区二区| 日韩欧美亚洲国产精品字幕久久久| 老司机午夜在线视频| 成人乱色短篇合集| 99国内精品久久久久久久| 手机av在线免费| 亚洲日本青草视频在线怡红院| 一区二区三区黄| 久青草国产97香蕉在线视频| 国产精品美女久久久久| 国产高潮呻吟久久久| 国产一二三精品| 久久精品一区二区三| 精品国产乱码久久久久久夜甘婷婷 | 95av在线视频| 亚洲乱码免费伦视频| 丰满少妇中文字幕| 一区二区三区在线视频观看58| 国产av精国产传媒| 久久久久久久久久国产精品| 精品自拍偷拍| 国产精品亚洲αv天堂无码| 久久久国产一区二区三区四区小说| 波多野结衣二区三区| 日韩在线视频网| 免费观看在线一区二区三区| www.国产在线视频| 久久久久久**毛片大全| 中文字幕精品无码亚| 久久亚洲欧美日韩精品专区 | 极品美女销魂一区二区三区| 极品色av影院| 精品av综合导航| 都市激情亚洲一区| 波多野结衣三级在线| 国产99久久久久久免费看农村| 97人人澡人人爽人人模亚洲| 亚洲欧美色图片| 国产精品美女久久久久人| av免费看网址| 欧美韩国日本不卡| av中文字幕观看| 欧美一级大片在线观看| 日韩成人影院| 黄色性视频网站| 在线观看欧美日本| 亚洲性图自拍| 日本一区二区在线视频| 国产久卡久卡久卡久卡视频精品| 亚洲视频免费播放| 最好看的2019年中文视频| 超碰成人97| 亚洲精品手机在线观看| 亚洲高清一区二区三区| av资源在线观看免费高清| 国产高清自拍一区| 免费观看在线综合| 国产精品16p| 精品久久久999| 一区二区三区四区在线看| 天天爽夜夜爽视频| 在线精品视频免费播放| av老司机免费在线| 蜜桃视频成人在线观看|