最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

TypeScript中泛型的使用詳細(xì)講解

 更新時(shí)間:2022年11月03日 09:34:48   作者:鄭建007  
泛型程序設(shè)計(jì)(generic programming)是程序設(shè)計(jì)語(yǔ)言的一種風(fēng)格或范式,下面這篇文章主要給大家介紹了關(guān)于TypeScript中泛型使用的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、泛型程序設(shè)計(jì)是一種編程風(fēng)格或編程范式

二、案例:傳入的參數(shù)類(lèi)型與返回的類(lèi)型一樣

function identify<T>(arg: T): T {// 當(dāng)前的T沒(méi)有任何約束 它可以是任何類(lèi)型
    return arg;
}
 
const foo = identify('foo'); // foo的類(lèi)型是'foo'
const bar = identify('true'); // bar的類(lèi)型是true

三、形式類(lèi)型參數(shù)

 1、形式類(lèi)型參數(shù)T的默認(rèn)類(lèi)型為boolean類(lèi)型

<T = boolean>

2、必選類(lèi)型參數(shù)、可選類(lèi)型參數(shù)

(1)、必選類(lèi)型參數(shù):形式類(lèi)型參數(shù)沒(méi)有給默認(rèn)類(lèi)型 , 例如: <T>

(2)、可選類(lèi)型參數(shù):形式類(lèi)型參數(shù)給默認(rèn)類(lèi)型 , 例如: <T = boolean>

(3)、形式類(lèi)型參數(shù)列表中,必選類(lèi)型參數(shù)不允許出現(xiàn)在可選類(lèi)型參數(shù)之后

<T = boolean, U> // 錯(cuò)誤
<T, U = boolean> // 正確

四、泛型約束

在形式類(lèi)型參數(shù)上允許定義一個(gè)約束條件,它能夠限定類(lèi)型參數(shù)的實(shí)際類(lèi)型的最大范圍。我們將類(lèi)型參數(shù)的約束條件稱為泛型約束

interface point {
    x: number,
    y: string
}
 
function getPoint<T extends point>(args: T): T {
    return args
}
 
console.log(getPoint({x: 123, y: 456})); // 錯(cuò)誤
console.log(getPoint({x: 123, y: '456'})); // 正確
console.log(getPoint({x: 123, y: '456', z: 678})); // 正確
//參數(shù)的前倆個(gè)必須有并且類(lèi)型必須正確  否則錯(cuò)誤

可以同時(shí)定義泛型約束和默認(rèn)類(lèi)型

<T extends number = 0 | 1>

泛型約束 ==> 類(lèi)型參數(shù)

<T, U extends T>
<T extends U, U>

形式類(lèi)型參數(shù)不允許直接或間接地將其自身作為約束類(lèi)型

<T extends T> // 錯(cuò)誤
<T extends U, U extends T> // 錯(cuò)誤

類(lèi)型參數(shù)T沒(méi)有聲明泛型約束,那么類(lèi)型參數(shù)T的基約束為空對(duì)象類(lèi)型字面量“{}”。除了undefined類(lèi)型和null類(lèi)型外,其他任何類(lèi)型都可以賦值給空對(duì)象類(lèi)型字面量

<T> // 類(lèi)型參數(shù)T的基數(shù)約為“{}”類(lèi)型

五、泛型函數(shù)

1.簡(jiǎn)介:若一個(gè)函數(shù)的函數(shù)簽名(形參)中帶有類(lèi)型參數(shù),那么它是一個(gè)泛型函數(shù) 

2.f1函數(shù)兩個(gè)參數(shù)的類(lèi)型相同,函數(shù)返回值類(lèi)型是數(shù)組,數(shù)組元素類(lèi)型 == 參數(shù)類(lèi)型。

function f1<T>(x: T, y: T): T[] {
    return [x, y]
}
 
const a = f1(123, 456)
const b = f1('123', '456')

3.f2函數(shù)兩個(gè)參數(shù)的類(lèi)型不同,返回值類(lèi)型為對(duì)象類(lèi)型。返回值對(duì)象類(lèi)型中x屬性的類(lèi)型與參數(shù)x類(lèi)型相同,y屬性的類(lèi)型與參數(shù)y類(lèi)型相同

function f2<T, U>(x: T,  y: U): { x: T, y: U} {
    return { x, y }
}
 
const a = f2('123', 456)
const b = f2(123, '456')

4.f3函數(shù)接受兩個(gè)參數(shù),參數(shù)a為任意類(lèi)型的數(shù)組;參數(shù)f是一個(gè)函數(shù),該函數(shù)的參數(shù)類(lèi)型與參數(shù)a的類(lèi)型相同,并返回任意類(lèi)型。f3函數(shù)的返回值類(lèi)型為參數(shù)f返回值類(lèi)型的數(shù)組。

(這個(gè)代碼的粘貼的   我也懵逼)

function f3<T, U>(a: T[], f: (x: T) => U): U[] {
    return a.map(f);
}
 
// f3<number, boolean> 約束T為number類(lèi)型  U為boolean類(lèi)型
const a: boolean[] = f3<number, boolean>([1, 2, 3], n => !! n)

六、泛型函數(shù)類(lèi)型推斷

function f0<T>(x: T): T {
    return x
}
 
const a = f0(123) // 推斷出類(lèi)型為 123
const b = f0('123') // 推斷出類(lèi)型為 '123'

此例中編譯器推斷出的不是number 和 string類(lèi)型,而是字符串字面量類(lèi)型123和“123”。因?yàn)門(mén)S原則,始終將字面量視為字面量類(lèi)型,只在必要的時(shí)候才會(huì)將字面量類(lèi)型放寬為某種基礎(chǔ)類(lèi)型,例如string類(lèi)型。此例中,字符串字面量類(lèi)型“123”是比string類(lèi)型更加精確的類(lèi)型。

類(lèi)型參數(shù)只在函數(shù)簽名中出現(xiàn)一次,則說(shuō)明它與其他值沒(méi)有關(guān)聯(lián),則不需要使用類(lèi)型參數(shù),直接聲明實(shí)際類(lèi)型即可。

幾乎任何函數(shù)都可以聲明為泛型函數(shù)。若泛型函數(shù)的類(lèi)型參數(shù)不表示參數(shù)之間或參數(shù)與返回值之間的某種關(guān)系,那么使用泛型函數(shù)可能是一種反模式。

// 沒(méi)必要使用泛型
function f<T>(x: T): void {
    console.log(x)
}
 
// 直接限定就好了
function f(x: number): void {
    console.log(x)
}

補(bǔ)充:應(yīng)用場(chǎng)景

通過(guò)上面初步的了解,后述在編寫(xiě) typescript 的時(shí)候,定義函數(shù),接口或者類(lèi)的時(shí)候,不預(yù)先定義好具體的類(lèi)型,而在使用的時(shí)候在指定類(lèi)型的一種特性的時(shí)候,這種情況下就可以使用泛型

靈活的使用泛型定義類(lèi)型,是掌握typescript 必經(jīng)之路

<泛型變量名稱>(參數(shù)1: 泛型變量, 參數(shù)2: 泛型變量, ...參數(shù)n: 泛型變量) => 泛型變量

 /*------------基礎(chǔ)使用方法------------*/
  function join<T, P>(first: T, second: P): T {
    return first;
  }
  //const twoParms = join<number, string>(1, '我是string');
  const twoParms = join(1, '我是string');

  /*---------泛型集合--------------*/
  function map<T>(params: Array<T>) {
    return params;
  }
  //const sanleType = map<string>(['123']);
  const sanleType = map(['123']);

  /* -----------泛型箭頭函數(shù)-------------*/
  const identity = <T,>(arg: T): T => {
    return arg;
  };
  const identity2: <T>(arg: T) => T = (arg) => {
    return arg;
  };

泛型接口

 /* -------------泛型接口-------------*/
 interface ColumnProps<T> {
  key: number | string;
  title: string;
  dataIndex: keyof T; // 約束 dataIndex 值需為引用泛型 T 中的屬性
}
interface ITableItem {
  key: number | string;
  name: string;
  address: string;
  age: number;
}
const columns: Array<ColumnProps<ITableItem>> = [
    {
      title: '姓名',
      dataIndex: 'name',
      key: 'name',
    },
  ];

泛型類(lèi)

 /*--------------泛型類(lèi)---------------*/
  class Person<T> {
    love: T;
    say: (arg: T) => T;
  }
  let myFn: IGeneric<number> = fn;
  myFn(13); //13
 
  let me = new Person<string>();
  me.love = 'TS';
  // me.love = 520; // ERROR
  me.say = function(love: string){
    return `my love is ${love}`;
  }

泛型約束

泛型可以通過(guò) extends 一個(gè)接口來(lái)實(shí)現(xiàn)泛型約束,寫(xiě)法如:

<泛型變量 extends 接口>

<T, K extends keyof T>
//K為傳入的T上已知的屬性,

interface IArray {
  length: number
}
function logIndex<T extends IArray>(arg: T): void {
  for (let i = 0; i < arg.length; ++i) {
    console.log(i)
  }
}
let arr = [1, 2, 3]
// logIndex<number>(arr) // 報(bào)錯(cuò)
logIndex<number[]>(arr) // 允許
logIndex(arr) // 自動(dòng)類(lèi)型推導(dǎo),允許

泛型應(yīng)用場(chǎng)景之一

/*-------------應(yīng)用場(chǎng)景start---------------------------*/
interface ColumnProps<T> {
  key: number | string;
  title: string;
  dataIndex: keyof T; // 約束 dataIndex 值需為引用泛型 T 中的屬性
}
interface ITableItem {
  key: number | string;
  name: string;
  address: string;
  age: number;
}
interface TableProps {
  dataSource: ITableItem[];
  columns: Array<ColumnProps<ITableItem>>;
}
const MyTable = (props: TableProps) => {
  const { dataSource, columns } = props;
  return <Table dataSource={dataSource} columns={columns} />;
};
const ApplcationMod = () => {
  const dataSource = [
    {
      key: '1',
      name: '金城武',
      age: 32,
      address: '西湖區(qū)湖底公園1號(hào)',
    },
    {
      key: '2',
      name: '吳彥祖',
      age: 42,
      address: '西湖區(qū)湖底公園1號(hào)',
    },
  ];

  const columns: Array<ColumnProps<ITableItem>> = [
    {
      title: '姓名',
      dataIndex: 'name',
      key: 'name',
    },
    {
      title: '年齡',
      dataIndex: 'age',
      key: 'age',
    },
    {
      title: '住址',
      dataIndex: 'address',
      key: 'address',
    },
  ];

  return (
    <div>
      <h3>泛型應(yīng)用場(chǎng)景</h3>
      <MyTable dataSource={dataSource} columns={columns} />
    </div>
  );
};

總結(jié)

到此這篇關(guān)于TypeScript中泛型使用的文章就介紹到這了,更多相關(guān)TypeScript泛型的使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

保康县| 金秀| 温宿县| 金阳县| 志丹县| 富民县| 宁津县| 宣威市| 肇庆市| 罗定市| 嵊州市| 永安市| 渭源县| 雷山县| 招远市| 西乌珠穆沁旗| 兰西县| 贵德县| 台州市| 唐山市| 垫江县| 友谊县| 韩城市| 绍兴县| 仙桃市| 龙井市| 武山县| 东乡县| 沙雅县| 台南县| 泰宁县| 鄂尔多斯市| 邛崃市| 田林县| 田东县| 连州市| 宝兴县| 永宁县| 永平县| 阳新县| 彰武县|