91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

TypeScript泛型如何使用

發布時間:2022-09-19 09:40:21 來源:億速云 閱讀:110 作者:iii 欄目:開發技術

本篇內容介紹了“TypeScript泛型如何使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

情景再現

這里針對一種情況,也是非常常見的一種情況:那就是

function identity(arg: number): number {
    return arg;
}

就是我接收一個number類型的參數,同時也返回一個number,那如果現在我想要接收一個string類型,同時也返回一個string,那么我就要再寫一個函數像這樣:

function identity2(arg: string): string{
    return arg;
}

那如果我現在想要void類型…????????????

可能大家會想,那全部都變成any不就行了?像下面這樣

function identity(arg: any): any {
    return arg;
}

使用any類型會導致這個函數可以接收任何類型的arg參數,這樣就丟失了一些信息:傳入的類型與返回的類型應該是相同的。 如果我們傳入一個數字,我們只知道任何類型的值都有可能被返回。

那這樣不就與我們一開始的設想不一致了嗎?我傳入Number,返回string,也不會報錯呀!????

因此,我們需要一種方法使返回值的類型與傳入參數的類型是相同的。 這里,我們使用了類型變量,它是一種特殊的變量,只用于表示類型而不是值。

function identity<T>(arg: T): T {
    return arg;
}

我們給identity添加了類型變量T。 T幫助我們捕獲用戶傳入的類型(比如:number),之后我們就可以使用這個類型。 之后我們再次使用了T當做返回值類型。現在我們可以知道參數類型與返回值類型是相同的了。 這允許我們跟蹤函數里使用的類型的信息。

????&zwj;????我們把這個版本的identity函數叫做泛型,因為它可以適用于多個類型。 不同于使用any,它不會丟失信息,像第一個例子那像保持準確性,傳入數值類型并返回數值類型。

使用泛型

第一種是,傳入所有的參數,包含類型參數

TypeScript泛型如何使用

第二種方法更普遍。利用了類型推論 &ndash; 即編譯器會根據傳入的參數自動地幫助我們確定T的類型

function identity<T>(arg: T): T {
    return arg;
}
let output = identity<string>("myString");
let output2 = identity("myString2"); 
console.log(output);
console.log(output2);

TypeScript泛型如何使用

注意我們沒必要使用尖括號(<>)來明確地傳入類型;編譯器可以查看myString的值,然后把T設置為它的類型。 類型推論幫助我們保持代碼精簡和高可讀性。如果編譯器不能夠自動地推斷出類型的話,只能像上面那樣明確的傳入T的類型,在一些復雜的情況下,這是可能出現的。

泛型類型

我們研究一下函數本身的類型,以及如何創建泛型接口。

來看看泛型類型不同的展現方式:

function identity<T>(arg: T): T {
    return arg;
}
let myFunction: <T>(arg:T) => T = identity;

我們也可以使用不同的泛型參數名,只要在數量上和使用方式上能對應上就可以。

function identity<T>(arg: T): T {
    return arg;
}
let myFunction: <T>(arg:T) => T = identity;
let myIdentity: <U>(arg: U) => U = identity;

我們還可以使用帶有調用簽名的對象字面量來定義泛型函數:

function identity<T>(arg: T): T {
    return arg;
}
let myIdentity: {<T>(arg: T): T} = identity;

是不是花了眼哈哈哈哈哈

泛型接口

還是以上面的為例子噢

interface GenericIdentityFn {
    <T>(arg: T): T;
}
function identity<T>(arg: T): T {
    return arg;
}
let myIdentity: GenericIdentityFn = identity;

可不可以詳細一點

一個相似的例子,我們可能想把泛型參數當作整個接口的一個參數。 這樣我們就能清楚的知道使用的具體是哪個泛型類型(比如:Dictionary< string>而不只是Dictionary)。 這樣接口里的其它成員也能知道這個參數的類型了。

interface GenericIdentityFn<T> {
    (arg: T): T;
}
function identity<T>(arg: T): T {
    return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;

泛型類

我等這個泛型類等了好久好久????????????

泛型類看上去與泛型接口差不多。 泛型類使用(<>)括起泛型類型,跟在類名后面。

// 泛型類
class GenericNumber<T> {
    zeroValue: T | undefined;
    add: ((x: T, y: T) => T) | undefined;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
function myAdd(x:number, y:number) { 
    return x + y; 
};
myGenericNumber.add = function(x, y) { 
    return x + y; 
};
console.log(myGenericNumber.add(1,2));

TypeScript泛型如何使用

換string玩玩

// 泛型類
class GenericNumber<T> {
    zeroValue: T | undefined;
    add: ((x: T, y: T) => T) | undefined;
}
let stringNumeric = new GenericNumber<string>();
stringNumeric.zeroValue = "hi,";
stringNumeric.add = function(x, y) { return x + y; };
console.log(stringNumeric.add(stringNumeric.zeroValue, "test"));

TypeScript泛型如何使用

也不是全能的

與接口一樣,直接把泛型類型放在類后面,可以幫助我們確認類的所有屬性都在使用相同的類型。

注意點??????類有兩部分:靜態部分和實例部分。 泛型類指的是實例部分的類型,所以類的靜態屬性不能使用這個泛型類型。

泛型約束

到底有沒有長度啊,救命

當我們使用泛型的時候,有這種情況:

我想要打印出傳過來的參數的長度為多少

function loggingIdentity<T>(arg: T): T {
    console.log(arg.length);  // Error: T doesn't have .length
    return arg;
}

這里會扯到一個問題,首先,你傳過來的這個玩意兒,它本身有長度嗎??

首先,什么樣的類型會有長度,毫無疑問,數組嘛

那我如果傳入的不是數組,那就鐵定報錯,就像上面那樣,正確的寫法大家也都懂:

function loggingIdentity<T>(arg: T[]): T[] {
    console.log(arg.length);  // Array has a .length, so no more error
    return arg;
}

相比于操作any所有類型,我們想要限制函數去處理任意帶有.length屬性的所有類型。 只要傳入的類型有這個屬性,我們就允許,就是說至少包含這一屬性。 為此,我們需要列出對于T的約束要求。

interface Lengthwise {
    length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);  // Now we know it has a .length property, so no more error
    return arg;
}

現在傳入一個數字試試

TypeScript泛型如何使用

傳入數組:

我們需要傳入符合約束類型的值,必須包含必須的屬性:

TypeScript泛型如何使用

在泛型里使用類類型[]

在TypeScript使用泛型創建工廠函數時,需要引用構造函數的類類型。

跟在Java中的很像&mdash;&mdash;工廠模式,很是高級

function create<T>(c: {new(): T; }): T {
    return new c();
}

高級案例

應用場景:傳入這個類,自動創建該類并且返回相應的屬性。

class BeeKeeper {
    hasMask: boolean = false;
}
class ZooKeeper {
    nametag:string =  "ZooKeeper.nametag";
}
class Animal {
    numLegs: number = 100;
}
class Bee extends Animal {
    keeper: BeeKeeper = new BeeKeeper();
}
class Lion extends Animal {
    keeper: ZooKeeper = new ZooKeeper();
}
function createInstance<A extends Animal>(c: new () => A): A {
    return new c();
}
console.log(createInstance(Lion).keeper.nametag); 
console.log(createInstance(Bee).keeper.hasMask);

TypeScript泛型如何使用

“TypeScript泛型如何使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

成武县| 德格县| 西乌珠穆沁旗| 安阳市| 滕州市| 响水县| 乐陵市| 临城县| 邛崃市| 吕梁市| 富源县| 娱乐| 洮南市| 北京市| 沙河市| 江阴市| 南通市| 双桥区| 荣昌县| 赫章县| 张家界市| 怀集县| 文登市| 稷山县| 鄂托克旗| 榆社县| 古浪县| 广饶县| 锡林郭勒盟| 崇义县| 改则县| 枝江市| 公主岭市| 马公市| 宜州市| 阳高县| 平武县| 积石山| 南城县| 都兰县| 广灵县|