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

TypeScript 5.0 beta 發布:新版 ES 裝飾器、泛型參數的常量修飾、枚舉增強等

開發 前端
由于 beta 版本與正式版本通常不會有明顯的差異,這一系列通常只會介紹 beta 版本而非正式版本。

TypeScript 已于 2023.01.26 發布 5.0 beta 版本,你可以在 5.0 Iteration Plan 查看所有被包含的 Issue 與 PR。如果想要搶先體驗新特性,執行:

$ npm install typescript@beta

來安裝 beta 版本的 TypeScript,或在 VS Code 中安裝 JavaScript and TypeScript Nightly 來更新內置的 TypeScript 支持。

本篇是筆者的第六篇 TypeScript 更新日志,上一篇是 「TypeScript 4.9 beta 發布:鴿置的 ES 裝飾器、satisfies 操作符、類型收窄增強、單文件級別配置等」,你可以在此賬號的創作中找到(或在掘金/知乎搜索林不渡),接下來筆者也將持續更新 TypeScript 的 DevBlog 相關,感謝你的閱讀。

另外,由于 beta 版本與正式版本通常不會有明顯的差異,這一系列通常只會介紹 beta 版本而非正式版本。

補充說明:TypeScript 并不使用 Semantic Version 規范,這意味著你不能將 x.0 作為一個 Major 版本——因為它可能并不包含破壞性更新,你也不能將 5.x 作為一個 Minor 版本——因為它可能就包含破壞性更新。

ECMASCript 裝飾器

ES 新版裝飾器終于在 5.0 中成功 Landing(部分關于其后續迭代的討論,請參考 #50820),以下對新版裝飾器 API 的介紹來自于筆者此前發表的 ECMAScript 雙月報告:裝飾器提案進入 Stage 3 。

一個最基本的裝飾器類型定義大致是這樣的:

type Decorator = (value: Input, context: {
kind: string;
name: string | symbol;
access: {
get?(): unknown;
set?(value: unknown): void;
};
isPrivate?: boolean;
isStatic?: boolean;
addInitializer?(initializer: () => void): void;
}) => Output | void;

value 為這個裝飾器應用處的類或類成員的值,而 context 則包含了這一被裝飾的值的上下文信息。這兩個參數都基于裝飾器實際應用的位置來決定,如果裝飾器的調用返回了一個值(Output),那么被裝飾位置的值會被這個返回值替換掉。

對于 context 參數,我們先對其內部的屬性做一個簡單介紹:

  • kind,被裝飾的值的類型,如 'class' / 'method' / 'field' 等,這一屬性可以被用來校驗裝飾器被應用在了正確的位置,或者在同一個裝飾器中,基于實際應用位置執行不同的裝飾邏輯。
  • name,被裝飾的值的名稱,如類名、屬性名、方法名等。
  • access,其包含了這個值的 getter 與 setter,我們會在下面詳細介紹。
  • isStatic 與 isPrivate,在裝飾器應用于類成員時提供這一成員的訪問性修飾符信息。
  • addInitializer,可以通過這個屬性添加要在類實例化時執行的邏輯。

需要注意的是,除了語義與參數的變化,新版的裝飾器在調用語法上也進行了一些調整:

  • 類表達式現在也可以應用裝飾器了,如:
const Foo = @deco class {
constructor() {}
}
  • 裝飾器與 export 關鍵字一同應用的方式調整為:
export default @deco class Foo { }

以下基于當前的裝飾器類型,對裝飾器的基本能力進行簡要介紹,類型定義來自于 5.0.0 beta 版本中的 lib.decorator.d.ts? 聲明文件,為了可讀性進行了略微修改。另外,context.access 屬性目前暫時被禁用,正在等待 #494 的討論得出結果。

類裝飾器

類裝飾器的類型定義如下:

type ClassDecorator = (value: Function, context: {
kind: "class";
name: string | undefined;
addInitializer(initializer: (this: Class) => void): void;
}) => Function | void;

value 為被裝飾的 Class,你可以通過返回一個新的 Class 來完全替換掉原來的 Class?;蛘哂捎谀隳苣玫皆鹊?Class,你也可以直接返回一個它的子類:

function logged(value, { kind, name }) {
if (kind === "class") {
return class extends value {
constructor(...args) {
super(...args);
}
}
}
}

@logged
class C {}

類方法裝飾器

類方法裝飾器的類型定義如下:

type ClassMethodDecorator = (value: Function, context: {
kind: "method";
name: string | symbol;
static: boolean;
private: boolean;
addInitializer(initializer: (this: This) => void): void;
}) => Function | void;

其 value 參數為被裝飾的類方法,可以通過返回一個新的方法來直接在原型層面代替掉原來的方法(對于靜態方法則在 Class 的層面替換)。或者你也可以包裹這個原來的方法,執行一些額外的邏輯:

function logged(value, { kind, name }) {
if (kind === "method") {
return function (...args) {
const ret = value.call(this, ...args);
return ret;
};
}
}

class C {
@logged
m(arg) {}
}

類屬性裝飾器

類屬性裝飾器的類型定義如下:

type ClassFieldDecorator = (value: undefined, context: {
kind: "field";
name: string | symbol;
access: { get(): unknown, set(value: unknown): void };
isStatic: boolean;
isPrivate: boolean;
}) => (initialValue: unknown) => unknown | void;

不同于上面的幾種裝飾器,屬性裝飾器的 value 并不是被裝飾的屬性的值,而是一個 undefined。如果要獲取被裝飾的屬性值,你可以讓屬性裝飾器返回一個函數,這個函數會在屬性被賦值時調用,拿到初始值作為入參,并可以返回一個新的值作為實際的賦值。

function logged(value, { kind, name }) {
if (kind === "field") {
return function (initialValue) {
return 599;
};
}

// ...
}

class C {
@logged x = 1;
}

new C().x; // 599

屬性訪問器裝飾器與 Auto Accessor 的介紹請參考上面的 TC39 會議報告,這里不再展開。同時,目前新版裝飾器中并不存在參數裝飾器。

如果你想了解更多新版裝飾器的實際使用,可以參考 with-new-decorators,其中包括了使用 Babel 和 TypeScript 5.0 中的新版裝飾器應用。

另外,你也可以參考 Mustard,這是一個基于新版裝飾器,不依賴元數據的命令行應用構建庫(Command Line App Builder),它的使用大概是這樣的:

import { MustardFactory, MustardUtils } from "mustard-cli";
import { RootCommand, Option, App, Utils, Input } from "mustard-cli/decorator";
import { CommandStruct, MustardApp } from "mustard-cli/cli";

type Template = "typescript" | "javascript";

@RootCommand()
class RootCommandHandle implements CommandStruct {
@Option("dry", "d", "dry run command to see what will happen")
public dry = false;

@Option("template", "t", "template to use")
public template: Template = "typescript";

@Input("directory to create the project in")
public dir: string = "./";

@Utils()
public utils!: MustardUtils;

public run(): void {
console.log(this.utils.colors.green("Hello World"));
}
}

@App({
name: "awesome-mustard-app",
commands: [RootCommandHandle],
})
class Project implements MustardApp {
onError(error: Error): void {
console.log(error);
}
}

MustardFactory.init(Project).start();

以上的應用構建了一個使用 awesome-mustard-app 作為命令的 CLI 應用,它的調用方式是這樣的:

$ create-awesome-app my-awesome-app --dry --template=typescript

如果你想體驗一下 Mustard CLI,可以執行以下命令:

$ pnpx create-mustard-app

$ cd mustard-app
$ npm install
$ npm run dev

目前 Mustard 仍在進一步完善中,文檔 也仍在編寫中,歡迎隨手點個 star ~

另外一點關于新版裝飾器需要說明的是,舊版裝飾器的好伙伴反射元數據(Reflect Metadata)目前并不支持與新版裝飾器一同使用,筆者的猜想是反射元數據提案可能會在 3 月或更晚的 TC39 會議上進行討論,大概率也需要進行數輪修改才能推進到 Stage 3。因此,如果你想提前開始使用新版裝飾器,短期內是指望不了元數據能力的。

然而我們知道,元數據是基于裝飾器實現依賴注入的重要手段,基于舊版裝飾器的框架基本都是一個套路:類的成員注入元數據,然后由工廠方法在實例化這個類的同時按照元數據來初始化成員。比如使用裝飾器的 NodeJs 框架中會這么寫:

@Controller('/user')
class UserController {
@Inject()
userService: UserService;

@Get('/query')
async queryUser() { }

@Post('/create')
async addUser() { }
}

UserService? 會作為類型的元數據被注入到 userService? 上,并在實例化時注入一個 UserService 實例。同時 queryUser 和 addUser 會分別被注冊為 GET /query? 和 POST /create? 的請求處理方法。缺少了元數據的類型信息注入,在新版裝飾器中我們暫時無法優雅地實現 UserService? 到 userService 的注入。

而在 Mustard 中,我們的應用場景暫時不依賴類型信息來實現實例屬性注入,而是只需要做命令行參數到屬性名的映射,然后將值注入即可。我們使用了 context.addInitializer,將裝飾器收集到的屬性名、初始值等信息強行替換掉實例內的屬性值,再由工廠方法按照這個 Initializer 描述來真正進行實例的初始化。

最后,舊版的 --experimentalDecorators 選項將會仍然保留,如果啟用此配置,則仍然會將裝飾器視為舊版,新版的裝飾器無需任何配置就能夠默認啟用。

泛型參數的常量修飾

在此前,函數中的泛型參數推導只能推導到基礎類型一級(即比字面量類型高出一個層級的類型),如 string? 、string[] 這樣:

declare function foo<T>(x: T): T;

foo('linbudu'); // string
foo([1, 2, 3]); // <number[]
// { name: string; techs: string[]; }
foo({ name: 'linbudu', techs: ['nodejs', 'typescript', 'graphql'] });

這其實類似于使用 let 聲明變量時的自動類型推導表現。

TypeScript 5.0 新增了對泛型參數的常量修飾(基本等價于常量斷言),被修飾的泛型參數在進行類型信息推導時,將推導到盡可能精確的字面量類型層級:

declare function foo<const T>(x: T): T;

foo('linbudu'); // 'linbudu'
foo([1, 2, 3]); // readonly [1, 2, 3]
// { name: 'linbudu'; techs: readonly ['nodejs', 'typescript', 'graphql'] }
foo({ name: 'linbudu', techs: ['nodejs', 'typescript', 'graphql'] });

// 如果不使用常量修飾,等價于此效果
foo({ name: 'linbudu', techs: ['nodejs', 'typescript', 'graphql'] } as const);

可以看到這里對于數組類型的類型推斷,其實基本等價于常量斷言后的類型:每一級的數組類型都加上了 readonly 修飾。

當被常量修飾的泛型參數為數組類型時,如果其泛型約束不包含 readonly,則推導出的類型將回歸到泛型約束來維持其可變狀態,否則才會是預期的常量推導:

declare function foo<const T extends readonly string[]>(args: T): T;

declare function bar<const T extends string[]>(args: T): T;

// [readonly ["a", "b", "c"]
foo(["a", "b" ,"c"]);
// string[]
bar(["a", "b" ,"c"]);

枚舉增強

TypeScript 5.0 中對枚舉進行了一次全面的能力增強,移除了此前諸如「枚舉計算成員必須位于字面量成員之后」、「僅允許在數字枚舉中定義計算成員」、「常量枚舉中不允許包含變量或表達式」的限制:

const BaseValue = 10;
const Prefix = "/data";

enum Values {
First = BaseValue,
// 此前會提示「枚舉成員必須具有初始化表達式」,現在會正確從 10 開始累加
Second,
Third,
}
enum Routes {
// 此前會提示「只有數字枚舉可具有計算成員,但此表達式的類型為“string”」
Parts = `${Prefix}/parts`,
Invoices = `${Prefix}/invoices`,
}

const enum ConstValues {
// 此前會提示「常量枚舉成員初始值設定項只能包含字面量值和其他計算的枚舉值」
First = BaseValue, // 10
Second, // 11
Third, // 12
}
const enum ConstRoutes {
// 此前會提示「常量枚舉成員初始值設定項只能包含字面量值和其他計算的枚舉值」
Parts = `${Prefix}/parts`, // "/data/parts"
Invoices = `${Prefix}/invoices`, // "/data/invoices"
}

這一變化的主要原因在于,此前 TypeScript 中存在數字枚舉和字符串枚舉兩種類型的枚舉,其中數字枚舉僅允許數字類型與計算屬性成員,不允許字符串類型,而字符串枚舉又僅允許數字或字符串枚舉成員:

const BaseValue = 10;
const Prefix = '/data';

enum Values {
First = BaseValue,
// 枚舉成員必須具有初始化表達式。
Second,
Third,
}
enum Routes {
// 只有數字枚舉可具有計算成員,但此表達式的類型為“string”。
Parts = `${Prefix}/parts`,
Invoices = `${Prefix}/invoices`,
}

而在 5.0 版本中將這兩種枚舉合并成了單一的、功能更強大的枚舉類型,其成員允許任何常量或表達式計算,并僅為常量成員賦予字符串。同時,現在一個枚舉類型將被視為其所有成員類型組成的聯合類型,如偽代碼 type Enum = Enum.A | Enum.B | Enum.C。

--verbatimModuleSyntax 配置

我們知道,TS 文件到 JS 文件的編譯過程主要包括三件事:類型信息擦除、語法降級、聲明文件生成。關于類型信息擦除,你應該能立刻想到包括類型定義和類型簽名,但實際上這里還包含著常常被忽略的類型導入。

import { User } from './user.model';

const user: User = {};

在這個例子中,我們很容易確定 User 只被作為類型使用,需要被移除(否則如果運行時不存在一個 User Class,就會出錯了),那么,如果 user.model.ts 中有這么一行代碼:

// 額外的副作用
setupUserModelMiddleware();

export class User {};

這個時候,如果把導入語句移除,可能就會導致代碼運行時出現異常。

一直以來,為了避免對導入語句的移除影響運行時代碼,TypeScript 使用了多種方式來確定一條導入語句能否被移除,如檢查對導入的使用,以及其在導出文件中是如何聲明的。

為了簡化類型導入的判斷工作,TypeScript 此前引入了 import type 語法來聲明僅類型導入,或成員級別的僅類型導入:

import type * as UserTypes from "./user";

import { type UserModel, UserMiddleware } from "./user";

對應的,還有一系列配置來進一步細粒度地控制行為,如 --importsNotUsedAsValues? 用于確認類型導入的使用(僅類型導入需要被顯式標記,而未被使用的值導入仍然將會保留),--preserveValueImports 用于顯式避免部分導入語句的移除(所有值導入都將被完整保留,避免 TypeScript 無法檢測其使用方式的情況)等等。

而在 5.0 版本,TypeScript 引入了新的配置 --verbatimModuleSyntax 來進一步簡化這些情況,它的作用就簡單多了:所有非僅類型導入/導出都會被保留,而僅類型導入/導出都會被移除。

moduleResolution 相關

這一部分包括了 --moduleResolution bundler? 與 Resolution Customization Flags 的相關介紹。

TypeScript 自 4.5 版本 來一直在持續改進 NodeJs 中的 ESM 支持,先后在 4.5 beta 與 4.7 正式中引入了 .mts、.cts? 擴展名,支持了 package.json? 中的 exports, imports, type 等字段,以及新的 compilerOption.module? 與 compilerOptions.moduleResolution? 值:node16? 與 nodenext,這些能力很好地改進了 TS + NodeJs + Pure ESM 的研發體驗,但實際上,前端er 們并不會僅僅使用 tsc 來進行編譯,而其他的編譯工具其實并沒有這么多彎彎繞繞。

舉例來說,NodeJs 中的 ESM 強制要求你的相對導入路徑攜帶擴展名,即 import ns from "./mod.mjs"?(你也可以使用 --experimental-specifier-resolution=node 配置來啟用自動地路徑解析),這主要是為了貼合 NodeJs 在服務器環境下的性能表現。然而大部分的構建工具其實不要求你這么做,它會融合 ESM 與 CJS 的模塊解析策略。

在 5.0 beta 版本,TS 引入了新的 moduleResolutio: bundler 配置,它會使用 NodeJs 的模塊解析策略,支持 ESM 語法,但不會強制你使用 ESM 的這些嚴格解析規則。同時 5.0 還引入了一系列細粒度的配置項來便于各個運行時與構建工具按照自己的需求進行調整:

  • --allowImportingTsExtensions?,此配置啟用后,在相對導入 TS 文件時就能夠攜帶上擴展名(.ts, .mts, .tsx,不包括 .cts ,因為 ESM 才是一家人)。但需要注意的是需要同時啟用 --noEmit 或者 --emitDeclarationOnly,這是因為這些文件導入路徑還需要被構建工具進行處理后才能正常使用,運行時本身是無法
  • --resolvePackageJsonExports,--resolvePackageJsonImports,這兩個配置將分別強制 TS 在讀取 來自 node_modules 中的導入時去解析 package.json 中的 exports 與 imports 字段。在 moduleResolution 被指定為 node16 / nodenext / bundler 時默認啟用。
  • --allowArbitraryExtensions?,啟用此配置后,TS 在導入一個非 JS/JSX/TS/TSX 擴展名的文件時,也會自動去查找其類型聲明。如導入 style.css 時將嘗試加載 style.d.css.ts 聲明文件:
/* style.css */
.app-container {}

.app-main-title {}
// style.d.css.ts
declare const css: {
appContainer: string;
appMainTitle: string;
};

export default css;

你可能會想,為什么是 .d.css.ts?,而不是 .css.d.ts? ? 這是因為 file.d.ts? 通常被視為 file.js/jsx? 的聲明文件,也就是 .css 其實被視為了不完整的 JS 文件名,這實際上是錯誤的行為。

這一配置主要是為了避免在支持這些導入的運行時或者構建工具中產生類型報錯(此前我們通常通過 declare module '*.css' 來實現),它對業務開發確實有著明顯的意義,社區可能又要為此涌現出一批新活了。

  • --customConditions?,NodeJs 支持在 package.json 的 exports 中指定 import / require / node / default 等值來設定其在不同條件(環境)下的文件入口。而這一配置則是為了更靈活地指定條件,如你可以在 tsconfig.json 中這樣配置:
{
"compilerOptions": {
"target": "es2022",
"moduleResolution": "bundler",
"customConditions": ["only-for-linbudu"]
}
}

這樣若是你的 npm 包 exports 中指定了這一條件,則它會將其視為最高優先級:

{
"name": "@linbudu/pkg",
"exports": {
".": {
"only-for-linbudu": "./private.mjs",
"node": "./public.mjs",
"import": "./public.mjs",
}
}
}

其他

類型全量導出

現在,你可以使用 export type * from 'module'? 或者 export type * as namespace from 'module' 來導出類型了:

// models/user.model.ts
export class UserModel {}

// models/index.ts
export type * as models from './user.model.ts';

// app.ts
import { models } from './models';

// √ 僅作為類型使用
const userModel: UserModel = {};

// × 不能被作為值使用
const userModel = new models.UserModel();

JSDoc 中的 @satisfies 與 @overload

TypeScript 4.9 版本中引入了用于進行安全 upcast 操作的 satisfies 操作符(參考 TypeScript 4.9 beta 發布:鴿置的 ES 裝飾器、satisfies 操作符、類型收窄增強、單文件級別配置等),而在 5.0 版本中,為了支持在 JavaScript 文件中使用 JSDoc 進行類型檢查的使用方式,現在你可以使用 @satisfies 標簽來檢查類型,但同時在上下文中保持使用從原先值推導出的類型(這也是 satisfies 和 類型斷言最大的差異):

// @ts-check

// 類型“{ name: string; }”不滿足預期類型“{ name: string; version: string; }”。
/**
* @satisfies {{name:string, version:string}}
*/
let pkg = {
name: "mustard-cli",
};

另外一個在本次被添加的 JSDoc 標簽是 @overload,它用于顯式標明每一個函數的重載簽名,從而配合類型檢查,如以下的例子:

// @ts-check

/**
* @param {string} value
* @return {void}
*/

/**
* @param {number} value
* @param {number} [maximumFractionDigits]
* @return {void}
*/

/**
* @param {string | number} value
* @param {number} [maximumFractionDigits]
*/
function printValue(value, maximumFractionDigits) {
}

printValue("hello!", 123)?  是一個錯誤的重載調用,但卻沒有提示報錯信息,但如果為重載簽名添加 @overload 標簽,TS 就能夠依次檢查其是否有符合的重載調用:

// @ts-check

/**
* @overload
* @param {string} value
* @return {void}
*/

/**
* @overload
* @param {number} value
* @param {number} [maximumFractionDigits]
* @return {void}
*/

/**
* @param {string | number} value
* @param {number} [maximumFractionDigits]
*/
function printValue(value, maximumFractionDigits) { }

// 類型“string”的參數不能賦給類型“number”的參數。
printValue("hello!", 123); // error!

廢棄功能

為了更好地迎接未來的 ECMAScript 演進,TypeScript 5.0 引入了對語言能力或配置項的廢棄計劃,以 keyofStringsOnly 配置為例,在 5.0 版本開始,啟用此配置將會獲得一條警告:

TS9998: Flag 'keyofStringsOnly' is deprecated and will stop functioning in TypeScript 5.5. Specify 'ignoreDeprecations: "5.0"' to silence this error

在下一階段(如 5.5 版本),你仍然可以指定 keyofStringsOnly ,它也不會拋出任何錯誤,但實際上它已經不再有作用。在最后一個階段(如 6.0 版本),指定此配置將會拋出一個錯誤。

在第一階段,你可以通過設置 ignoreDeprecations: "5.0" 來關閉所有由于使用在 5.0 版本開始廢棄的功能而產生的警告。

已經確定在 5.0 版本將開始逐步廢棄的配置項包括 charset,noImplicitUseStrict,keyofStringsOnly,noFallthroughCasesInSwitch? 等,以及 target: ES3?  與 module: umd/system/amd。

tsconfig.json 多繼承

TypeScript 5.0 支持了 tsconfig.json 的 extends 配置的數組類型,用于同時繼承一組已有的規則,這一能力使得你能夠將自己的共享配置進一步拆解,再依據實際情況進行組合:

{
"extends": ["./tsconfig.modern.json", "./tsconfig.node.json", "./tsconfig.strict.json"]
}

以上這個配置集成了包含現代語言特性配置、包含 Node 應用配置以及包含嚴格檢查的配置文件。

單文件級別配置

TypeScript 5.0 現在支持單文件級別的配置,如你只想為當前文件啟用嚴格檢查,其他文件仍然使用全局配置,可以這么做:

// @ts-strict

// 參數 input 隱式具有 any 類型
const handler = (input) => input + 1;

目前支持的規則:

  • strict
  • noImplicitAny
  • strictNullChecks
  • strictFunctionTypes
  • strictBindCallApply
  • strictPropertyInitialization
  • noImplicitThis
  • useUnknownInCatchVariables
  • alwaysStrict
  • noUnusedLocals
  • noUnusedParameters
  • exactOptionalPropertyTypes
  • noImplicitReturns
  • noFallthroughCasesInSwitch
  • noUncheckedIndexedAccess
  • noImplicitOverride
  • noPropertyAccessFromIndexSignature

其配置項也均為小駝峰轉中劃線,如 @ts-no-property-access-from-index-signature。

責任編輯:武曉燕 來源: 林不渡也不是不能渡
相關推薦

2023-03-17 07:05:41

TypeScriptJSDoc 功能

2024-02-26 00:00:00

TypeScript裝飾器decorators

2009-03-05 09:25:11

2009-06-23 21:02:42

Linux

2021-12-15 12:59:56

Go泛型版Beta1

2022-09-26 09:02:54

TS 裝飾器TypeScript

2021-08-04 08:33:59

TypeScriptConst Readonly

2021-10-17 13:10:56

函數TypeScript泛型

2023-08-07 16:07:42

2021-12-15 10:23:56

Go 1.18 Bet語言泛型

2011-05-05 09:17:41

Firefox 5.0

2022-06-19 22:54:08

TypeScript泛型工具

2023-01-05 17:13:28

TypeScript泛型組件

2009-08-18 09:32:21

Silverlight

2024-04-23 08:23:36

TypeScript泛型Generics

2024-09-29 08:35:34

TypeScript枚舉安全性

2024-11-05 09:11:09

TypeScript開發者代碼

2012-04-19 09:50:53

Chrome 19Be新版發布

2009-06-24 09:21:20

Zend Studio

2011-06-16 09:25:17

Firefox 5.0
點贊
收藏

51CTO技術棧公眾號

国产一级网站视频在线| 中文在线一区二区三区| 日本在线免费| 国产成人亚洲综合a∨婷婷图片| 九九热精品在线| 国产伦理在线观看| 成人免费影院| 中文字幕一区二区三区av| 91免费在线视频| 亚洲激情视频一区| 欧美日韩在线播放视频| 日韩一区二区免费电影| www国产精品内射老熟女| 1769视频在线播放免费观看| 粉嫩欧美一区二区三区高清影视| 日韩免费av一区二区| 国产肥白大熟妇bbbb视频| 国产高清日韩| 日本高清无吗v一区| 路边理发店露脸熟妇泻火| 亚洲 欧美 激情 小说 另类| 久88久久88久久久| 欧美中在线观看| 久久免费黄色网址| 清纯唯美日韩| 亚洲免费伊人电影在线观看av| 久久黄色片网站| 成人免费看黄| 亚洲成av人片一区二区三区| 正在播放91九色| 精品无人乱码| 不卡的电视剧免费网站有什么| 国产精品自产拍在线观| 亚洲欧美偷拍视频| 影音先锋中文字幕一区二区| 日韩综合视频在线观看| 性猛交ⅹxxx富婆video| 欧美理论电影在线精品| 欧美电影免费观看完整版| 日本中文字幕精品—区二区| av日韩亚洲| 精品国产精品自拍| 中国丰满熟妇xxxx性| 2024最新电影免费在线观看| 国产精品丝袜一区| 日日夜夜精品网站| 九色视频成人自拍| 99精品1区2区| 欧美一区二区三区性视频| 国产成人午夜视频网址| 97人人澡人人爽人人模亚洲 | 91免费看网站| 亚洲一区二区色| 免费人成精品欧美精品| 国产精品高清在线| 国产情侣呻吟对白高潮| 日韩成人精品视频| 国产精品嫩草影院久久久| 国产99免费视频| 日韩主播视频在线| 国产精自产拍久久久久久蜜| 伊人网站在线观看| 久久99国产乱子伦精品免费| 成人免费网站在线看| 国产乱叫456在线| 国产精品一区2区| 成人动漫视频在线观看免费| 蜜桃视频污在线观看| av一区二区三区四区| 成人两性免费视频| 日韩人妻精品中文字幕| 久久久久久婷| 国产精品视频网址| 国产三级伦理片| 国产成人在线影院| 国产色综合一区二区三区| 无码国精品一区二区免费蜜桃| www.成人在线| 六月婷婷久久| 九九热视频在线观看| 国产精品毛片无遮挡高清| 亚洲精品乱码久久久久久蜜桃91| 91网页在线观看| 中文字幕在线观看一区| 妞干网这里只有精品| 午夜伦理在线视频| 亚洲电影一区二区| 各处沟厕大尺度偷拍女厕嘘嘘| 日本一级理论片在线大全| 亚洲成人av一区二区| 性一交一乱一伧国产女士spa| 黑人巨大猛交丰满少妇| 亚洲精品伊人| 日韩精品综合一本久道在线视频| 天堂网成人在线| 老司机aⅴ在线精品导航 | 97av视频在线观看| 日本精品另类| 欧美一区二区三区啪啪| 午夜免费福利影院| 国产探花在线精品| 欧美大片免费观看| www.欧美色| 国产在线精品免费| 精品亚洲欧美日韩| 91亚洲欧美| 偷窥少妇高潮呻吟av久久免费| 精品久久久久久无码国产| 亚洲成人a级片| 日韩第一页在线| av片在线免费看| 激情综合在线| 国产精品女主播| 亚洲成熟女性毛茸茸| 久久亚洲私人国产精品va媚药| 一区二区在线中文字幕电影视频 | 久久性感美女视频| 久久久人成影片一区二区三区观看| 日日摸天天添天天添破| 国产一区二区三区免费| 欧美日韩系列| 黄色成人在线网| 欧美日韩一区在线观看| 日韩精品视频一区二区| 欧美freesextv| 欧美一乱一性一交一视频| 国产精品探花视频| 久久久精品天堂| 精品无码国产一区二区三区av| 日韩福利影视| 亚洲欧美日韩国产精品| 久久久久久国产精品视频 | 亚洲午夜电影在线| 日本超碰在线观看| 一区二区三区日本久久久 | 精品在线视频一区二区三区| 18av在线视频| 欧美日韩一区高清| 少妇光屁股影院| 黑人一区二区三区四区五区| 91社区国产高清| sese在线视频| 日本韩国欧美一区| 国产男女猛烈无遮挡a片漫画| 黑人一区二区三区四区五区| 亚洲在线一区二区| 91青青在线视频| 在线观看视频一区| 美女100%露胸无遮挡| 亚洲综合国产激情另类一区| 国产精品久久久久久久天堂第1集 国产精品久久久久久久免费大片 国产精品久久久久久久久婷婷 | 国产精品久久午夜| 91人人澡人人爽人人精品| 亚洲小说图片视频| 97成人在线视频| 人妻中文字幕一区| 亚洲国产精品尤物yw在线观看| 日本77777| 国产精品麻豆久久| 成人午夜激情网| 自拍视频在线免费观看| 欧美亚洲综合色| 国产三级av在线播放| 久久久综合网| 欧美性天天影院| 深夜成人影院| 国产一区二区日韩精品欧美精品| 日韩欧美三级视频| 久久久久综合网| 国产自偷自偷免费一区 | 亚洲国产日韩一区| 免费日韩一级片| 久久色.com| 久久午夜夜伦鲁鲁一区二区| 激情五月色综合国产精品| 国产精品视频xxx| 日本a级在线| 亚洲国产美女精品久久久久∴| 久久精品免费av| heyzo一本久久综合| 欧美精品一区免费| 色噜噜狠狠色综合网图区| 人体内射精一区二区三区| 99久久99九九99九九九| 色妞久久福利网| 欧美 国产 精品| 日韩欧美中文字幕一区二区三区 | 国产后入清纯学生妹| 亚洲女同一区二区| 男人操女人下面视频| 国产欧美日韩亚洲一区二区三区| 成人黄色片网站| 天天色棕合合合合合合合| 亚洲aⅴ怡春院| 香蕉视频黄色在线观看| 日韩不卡一区二区| 裸体大乳女做爰69| 粉嫩av一区二区| 国产精品久久久av久久久| 黄色免费在线观看网站| 精品99999| 波多野结衣小视频| 亚洲欧美韩国综合色| bl动漫在线观看| 免费在线观看一区二区三区| 99视频精品全部免费看| 色天天色综合| 国产精品视频公开费视频| heyzo中文字幕在线| 亚洲网在线观看| 精品国产九九九| 色综合久久综合网97色综合| 日韩一区二区三区四区视频| 成人免费视频网站在线观看| 日本a√在线观看| 国产综合精品| 欧美亚洲爱爱另类综合| 亚洲一区二区三区日本久久九| 欧美一乱一性一交一视频| 久草免费在线观看| 日韩电影第一页| 99久久精品国产一区色| 色婷婷激情综合| 欧美性x x x| 国产精品三级av| 右手影院亚洲欧美| 国产1区2区3区精品美女| 国产wwwxx| 国产精品五区| 国产大尺度在线观看| 日韩欧美综合| 欧美日本韩国国产| 国产精品久久久网站| 成人免费自拍视频| 免费观看成人性生生活片| 国产精品精品| 国产伦精品一区二区三区照片91| 欧美视频在线视频精品| 色88888久久久久久影院| 另类专区欧美制服同性| 偷拍自拍在线| 亚洲成人久久一区| 国内精品久久久久久久久久| 欧美日韩国产电影| 男人天堂视频网| 精品女厕一区二区三区| 日韩精品无码一区二区| 亚洲午夜电影在线观看| 欧美日韩亚洲国产另类| 国产精品嫩草久久久久| 美女脱光内衣内裤| 久久久久成人黄色影片| 男人的天堂免费| 成人精品视频.| 四虎国产精品免费| 国产成人在线视频免费播放| 制服下的诱惑暮生| 国产精品综合二区| 欧美体内she精高潮| 蜜桃一区二区三区四区| 污污视频网站在线| 国产在线精品国自产拍免费| 亚洲一级片av| 国产精品自拍一区| 久久无码专区国产精品s| 国产成人久久精品77777最新版本| 91精品人妻一区二区三区四区| 国产成人在线网站| 天堂va欧美va亚洲va老司机| 本田岬高潮一区二区三区| 自拍视频第一页| 成人黄色在线看| 亚洲观看黄色网| 99国产精品视频免费观看| 精品人妻一区二区三区视频| 久久久噜噜噜久久人人看 | 国产精品一页| 国产精品-区区久久久狼| 久久综合九色| 免费看国产黄色片| 狠狠色丁香婷婷综合| 在线观看网站黄| 91在线云播放| 在线观看日本中文字幕| 国产日韩欧美亚洲| 成人一级黄色大片| 亚洲综合免费观看高清完整版在线 | 在线成人午夜影院| 91国产免费视频| 日韩欧美国产综合在线一区二区三区| 日本黄色三级视频| 在线精品视频视频中文字幕| 秋霞成人影院| 91成人性视频| 少妇精品视频一区二区免费看| 国产欧美久久一区二区| 亚洲精品一区在线| 欧美日本韩国国产| 中文精品电影| 精品999在线| 福利一区在线观看| 日韩丰满少妇无码内射| 亚洲人成在线观看一区二区| 久久久久99精品成人片毛片| 精品福利视频导航| jlzzjlzz亚洲女人18| 亚洲男人天堂视频| 成码无人av片在线观看网站| 97av在线视频| 精品一区二区三区免费看| 黄色国产精品一区二区三区| 欧美99在线视频观看| 男人插女人视频在线观看| 麻豆免费看一区二区三区| 亚洲美女在线播放| 一级中文字幕一区二区| 波多野结衣视频在线看| 亚洲成人亚洲激情| 日本激情视频在线观看| 欧美在线视频观看| 性欧美1819sex性高清| 精品福利影视| 欧美一区网站| 久久精品影视大全| 91日韩一区二区三区| 日韩美女视频在线| 性欧美videos另类hd| 亚洲欧美日韩综合| 欧美78videosex性欧美| 国产精品久久二区| 婷婷亚洲精品| 成人毛片一区二区| 国产在线精品一区二区不卡了| 很污很黄的网站| 91久久精品国产91性色tv| 黄色三级网站在线观看| 欧美成人精品xxx| 四虎在线精品| 亚洲欧洲免费无码| 男男成人高潮片免费网站| 久久久精品人妻无码专区| 亚洲二区视频在线| 精品国自产在线观看| 久久精品91久久久久久再现| 成人黄色视屏网站| 国产精品国产三级国产专区53| 欧美视频日韩| 国产在线a视频| 亚洲激情自拍视频| 11024精品一区二区三区日韩| 久久精品成人欧美大片| 久久电影天堂| 亚洲精品日韩成人| 蜜桃av噜噜一区| 波多野结衣片子| 欧美三级韩国三级日本一级| 国产三级在线免费| 国产精品高潮呻吟久久av黑人| 偷拍自拍一区| 99热在线这里只有精品| 久久久电影一区二区三区| 4438国产精品一区二区| 亚洲图片欧洲图片av| 2019年精品视频自拍| 91免费视频黄| 国产91富婆露脸刺激对白| 免费人成在线观看| 精品国产乱码久久久久久老虎| 福利在线导航136| 国产精品日韩一区二区| 另类天堂av| 日韩精品电影一区二区三区| 欧美日韩小视频| 国产黄a三级三级三级av在线看| 亚洲综合av影视| 国产精品毛片| 熟女少妇内射日韩亚洲| 欧美色涩在线第一页| 成人国产免费电影| 精品欧美一区二区在线观看视频 | 亚洲精品中文字幕有码专区| 日韩网站中文字幕| 日韩人妻一区二区三区蜜桃视频| 福利一区福利二区| 黄色一级片免费在线观看| 国产一区二区三区毛片| 国产精品1区在线| 日韩精品视频一区二区在线观看| 国产欧美精品一区二区三区四区 | 国产日韩精品中文字无码| 在线观看的黄色| 91精品国产高清久久久久久91| 国产精品自在线拍| 拔插拔插海外华人免费| 欧美激情在线免费观看| 成人在线免费观看视频网站| 国产乱对白刺激视频不卡| 国产一级精品视频| 这里只有精品在线播放| 网站一区二区|