TypeScript 學習筆記 — 類型相容 (十)

来源:https://www.cnblogs.com/echoyya/archive/2023/03/20/17189305.html
-Advertisement-
Play Games

TS 是結構類型系統(structural type system),基於結構/形狀檢查類型,而非類型的名字。 TS 中的相容性,主要看**結構是否相容**。(核心是考慮安全性),結構化的類型系統(又稱鴨子類型檢查),如兩個類型名字不一樣但是無法區分 類型相容性是基於結構子類型的。 結構類型是一種只 ...


目錄
TS 是結構類型系統(structural type system),基於結構/形狀檢查類型,而非類型的名字。

TS 中的相容性,主要看結構是否相容。(核心是考慮安全性),結構化的類型系統(又稱鴨子類型檢查),如兩個類型名字不一樣但是無法區分
類型相容性是基於結構子類型的。 結構類型是一種只使用其成員來描述類型的方式。

如果x要相容y,那麼y至少具有與x相同的屬性。
這裡要檢查y是否能賦值給x,編譯器檢查x中的每個屬性,看是否能在y中也找到對應屬性。
X 相容 Y:X(目標類型)= Y(源類型)
簡單一句話概括相容性: 重新賦值不報錯(類型自動轉化)

一.基本數據類型的相容性

let temp: string | number;
let num!: number;
temp = num;
let obj: {
  toString(): string;
};
let str: string = "yya";
obj = str; // 字元串中具備toString()方法,所以可以進行相容
obj.toString(); // 安全, 保證使用的時候不會發生異常

二.介面相容性

介面的相容性,只要滿足介面中所需要的類型即可!(保證你要的,我都有,就行,多了也沒關係)

interface IAnimal {
  name: string;
  age: number;
}
interface IPerson {
  name: string;
  age: number;
  address: string;
}
let animal: IAnimal;
let person: IPerson = {
  name: "yya",
  age: 18,
  address: "beijing",
};

type T2 = IPerson extends IAnimal ? true : false; // true
animal = person; // 子類賦予給父類 相容

三.函數的相容性

函數的相容性主要是比較參數和返回值

參數:賦值函數的參數要少於等於被賦值的函數:也就是說,對應函數的參數來講,少的參數可以賦予給多的,因為內部實現傳了多個可以少用或不用(忽略額外的參數在 JavaScript 里是很常見的)

sum2的每個參數必須能在sum1里找到對應類型的參數。 註意的是參數的名字相同與否無所謂,只看它們的類型sum2的每個參數在sum1中都能找到對應的參數,所以允許賦值。

let sum1 = (a: string, b: string) => a + b;
let sum2 = (a: string) => a;
sum1 = sum2;

舉例: Array#forEach給回調函數傳 3 個參數:item,index 和 array。 儘管如此,傳入一個只使用第一個參數的回調函數也是可以的

type Func<T> = (item: T, index: number, array: any[]) => void;
function forEach<T>(arr: T[], cb: Func<T>) {
  for (let i = 0; i < arr.length; i++) {
    cb(arr[i], i, arr);
  }
}
forEach([1, 2, 3], (item) => {
  console.log(item);
});

返回值:

type sum1 = () => string | number;
type sum2 = () => string;

let fn1: sum1;
let fn2!: sum2;
fn1 = fn2;

四.類的相容性

類與對象字面量和介面差不多,但有一點不同:類有靜態部分和實例部分的類型。 比較兩個類類型的對象時,只有實例的成員會被比較。 靜態成員和構造函數不在比較的範圍內。

class Animal {
  feet!: number;
  constructor(name: string, numFeet: number) {}
}

class Size {
  feet!: number;
  constructor(numFeet: number) {}
}

let a!: Animal;
let s!: Size;

a = s; // OK
s = a; // OK

類的私有成員和受保護成員

只要有 private 或者 protected 關鍵字會影響相容性, 當檢查類實例的相容時,如果目標類型包含一個 private 私有成員,那麼源類型必須包含來自同一個類的這個私有成員。 這條規則也適用於包含 protected 受保護成員實例的類型檢查。 允許子類賦值給父類,但是不能賦值給其它有同樣類型的類。

class A {
  private name!: string;
  age!: number;
}

class B {
  private name!: string;
  age!: number;
}

// let a: A = new B();  // error

class Parent {
  protected name: string = "zf";
  age: number = 11;
}
class Child extends Parent {}
let child: Parent = new Child(); // ok

五.泛型的相容性

泛型比較的是最終的結果 比較的不是泛型傳遞的參數
例一:

interface Empty<T> {}

let x: Empty<number>;
let y!: Empty<string>;

type xx = Empty<number> extends Empty<string> ? true : false; // true

x = y; // OK 因為 y 匹配 x 的結構

在例一中,x 和 y 是相容的,因為它們的結構使用類型參數時並沒有什麼不同。 把這個例子改變一下,增加一個成員,就能看出是如何工作的了:
例二:

interface NotEmpty<T> {
  data: T;
}
let x: NotEmpty<number>;
let y: NotEmpty<string>;

type xx = NotEmpty<number> extends NotEmpty<string> ? true : false; // false

x = y; // Error,  不相容

對於沒指定泛型類型的泛型參數時,會把所有泛型參數當成 any 比較。 然後用結果類型進行比較,就像例一:

let identity = function <T>(x: T): T {};

let reverse = function <U>(y: U): U {};

identity = reverse; // OK,  (x: any) => any 匹配 (y: any) => any

六.枚舉的相容性

枚舉類型與數字類型相容,並且數字類型與枚舉類型相容

enum Status {
  Pending,
  Resolved,
  Rejected,
}

let current = Status.Pending;
let num = 0;

current = num;
num = current;

不同枚舉類型之間是不相容的。

enum Status {
  Pending,
  Resolved,
  Rejected,
}
enum Color {
  Red,
  Blue,
  Green,
}

let current = Status.Pending;
let color = Color.Red;

current = color; // 不能將類型“Color.Red”分配給類型“Status”

標稱類型簡短介紹

類型分為兩種 結構化類型(structural type system) 、標稱類型(nominal type system)
標稱類型: 雖然 BTC,USDT 都是 number 類型,但還是想要用不同的類型表示,且不能互換,數據的值本身沒什麼區別,安上不同名字就是不同類型,也就是說,標稱類型系統中,兩個變數是否類型相容(可以交換賦值)取決於這兩個變數顯式聲明的類型名字是否相同。

class AddType<S> {
  private _type!: S;
}
type NewType<T, S extends string> = T & AddType<S>;

type BTC = NewType<number, "btc">; // number + BTC
type USDT = NewType<number, "usdt">; // number + USDT
let btc = 100 as BTC;
let usdt = 100 as USDT;

function getCount(count: USDT) {
  return count;
}
getCount(usdt);

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MySQL資料庫的安裝 (如果安裝失敗請看鏈接https://www.cnblogs.com/seeyouone/p/17236660.html) 註意: 必須用系統管理員身份運行mysql安裝程式。 安裝目錄切記不要用中文。 步驟一:雙擊mysql8的安裝嚮導 步驟二:安裝 (1)如果是首次安裝m ...
  • 步驟一:軟體的卸載準備 學習網路編程時,TCP/IP協議程式有伺服器端和客戶端。mysql這個資料庫管理軟體是使用TCP/IP協議。我們現在要卸載的是mysql的伺服器端,它沒有界面。 【計算】-->右鍵-->【管理】-->【服務】-->【mysql的服務】-->【停止】 步驟二:軟體的卸載 方式一 ...
  • 重要的話先說,今晚(3月20日)19:30 gt-checksum新版本發佈會,點擊下麵的鏈接預約: 會議詳情 (tencent.com) gt-checksum 1.2.0版本發佈後,受到了廣大社區用戶的熱烈響應。短短幾天,便有幾十個star,以及社區用戶提交了十幾條issue反饋問題,更有熱心用 ...
  • 前言 在initEvents中發現的有意思的東西,就是 Vue 針對 Error 的處理,說實話之前壓根沒在意過 Vue 是如何收集處理 Error 的; errorHandler:https://v2.cn.vuejs.org/v2/api#errorHandler ?> 從 2.2.0 起,這個 ...
  • (目錄) Ajax 工作原理 Ajax Ajax 是前後端非同步交互的工具,非同步更新,ajax 包含 XMLHttpRequests 對象(非同步地與伺服器交換數據,AJAX 核心) JavaScript/DOM(信息顯示/交互) CSS(給數據定義樣式) XML 或 JSON(作為轉換數據的格式) 工 ...
  • 其他章節請看: webgl 系列 繪製貓 上文我們瞭解瞭如何繪製漸變彩色三角形,明白了圖形裝配、光柵化,以及片元著色器計算片元的顏色。 現在如果讓你繪製如下一隻貓。難道繪製很多三角形,然後指定它們的顏色?那樣簡直太難、太繁瑣了。 這時可以使用三維圖形學中的紋理映射技術來解決這個問題。 紋理映射簡單來 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 對於前端人員來講,最令人頭疼的應該就是頁面性能了,當用戶在訪問一個頁面時,總是希望它能夠快速呈現在眼前並且是可交互狀態。如果頁面載入過慢,你的用戶很可能會因此離你而去。所以頁面性能對於前端開發者來說可謂是重中之重,其實你如果瞭解頁面 ...
  • 本文旨在從0到1的講述一下我們團隊在做系統可觀測性過程中所沉澱下來的一整套解決方案,收效甚巨,不敢苟藏,當公之於眾,共建吾輩光明之未來。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...