TypeScript系列:第六篇 - 編寫高質量的TS類型

掌握這些,ts類型聲明事半功倍 💪🏻

不要做

  • 永遠不要使用類型 NumberStringBooleanSymbolObject 這些類型指的是非原始裝箱對象,使用 numberstringbooleansymbol 類型
  • 不要使用 any 作為類型,除非正在將 JavaScript 項目遷移到 TypeScript
  • 不要將返回類型 any 用于其值將被忽略的回調,使用返回類型 void,其可以防止意外地以未經檢查的方式使用函數的返回值 const fun = (fn: () => void) => {};

declare 作用?

declare關鍵字在 TypeScript 中主要用于聲明類型信息,而不是實際的實現代碼。其幫助 TypeScript 理解代碼中的類型結構,從而提供更好的類型檢查和代碼提示等功能。

聲明全局變量類型

當在項目中使用了某些全局變量,而這些變量沒有明確的類型定義時,可以使用declare來聲明它們的類型。

declare const globalVar: string;

如,在 UmiJS 框架 中,針對全局變量聲明類型:

// typings.d.ts
declare function log(info: string): void; 
declare global {type AnalysisFunction = (params: { pageId: string; eventId: string; ext?: object }) => void;interface Window: {// 基座掛載window判斷權限方法PermissionAuth?: (params: {// 頁面唯一標識pk: string;// 按鈕唯一標識fk?: string;}) => boolean;}
}

聲明模塊

如果要使用一個外部模塊,但這個模塊沒有提供 TypeScript 的類型定義文件(.d.ts),可以通過declare module來聲明它的類型。

declare module 'my-custom-module' {export function doSomething(): void;
}

.d.ts.ts 區別?

  • .d.ts:第三方庫提供類型聲明、聲明全局變量或全局類型、擴展現有模塊的類型聲明

    // jquery.d.ts
    declare var jQuery: {(selector: string): any;ajax: {(url: string, settings?: any): void;};
    };
    
  • .ts:定義實際的類型和接口,并且這些類型和接口將被項目中的其他代碼使用時,或者在項目內部進行模塊化開發時

    // user.ts
    export interface User {id: number;name: string;email: string;
    }
    

import typeimport 區別?

  • import type:用于導入類型信息,但不會將導入的模塊包含在運行時代碼中。它主要用于類型聲明,不會影響最終的 JavaScript 輸出

    // main.ts
    import type { User } from './types';
    
  • import:用于導入模塊中的值(如變量、函數、類等),這些值在運行時會被加載和執行。它不僅用于類型聲明,還用于實際的代碼運行

extends 擴展類型

interface 上的 extends 關鍵字允許從其他命名類型復制成員,并添加任何新成員。

這對于減少類型聲明的數量以及表明同一屬性的幾個不同的意圖很有用。

interface Person {name: string;age: number;
}
// 類型擴展
interface Man extends Person {readonly sex: '男';
}interface SpecialSkill {fly: () => void;
}
// 也可以從多種類型擴展
interface Superman extends Man, SpecialSkill {}

typeofkeyof 區別?

  • typeof 操作符用于獲取一個變量或屬性的類型

  • keyof 操作符用于獲取一個對象類型的所有鍵的聯合類型

interface IPerson {name: string;age: number;
}type PersonKey = keyof IPerson; // 類型是 "name" | "age"
const p: PersonKey = 'age';
const pType = typeof p; // string

更多內容,可詳見:TypeScript系列:第四篇 - typeof 與 keyof

extends keyof 類型約束

在動態訪問和操作對象屬性時保持類型安全,避免運行時錯誤。

<TData, TLabelKey extends keyof TData> 定義兩個泛型參數TDataTLabelKey

  • TData表示傳入的對象類型
  • TLabelKey表示對象中的某個鍵,該鍵必須是TData對象的一個鍵(通過extends keyof TData約束)
動態訪問對象屬性

動態地訪問對象的某個屬性時,可以使用這種約束來確保訪問的屬性是有效的。

interface TData {city: string;adcode: number;
}// labelKey必須是data對象的鍵之一
function getValue<TData, TLabelKey extends keyof TData>(data: TData, labelKey: TLabelKey): TData[TLabelKey] {return data[labelKey];
}
動態生成對象屬性
interface TData {city: string;adcode: number;
}// labelKey必須是data對象的鍵之一,value的類型必須與data[labelKey]的類型一致
function setProperty<TData, TLabelKey extends keyof TData>(data: TData, labelKey: TLabelKey, value: TData[TLabelKey]): TData {data[labelKey] = value;return data;
}

!非空斷言

在不進行任何顯式檢查的情況下從類型中刪除 nullundefined

function liveDangerously(x?: number) {return x.toFixed(); 	// x可能為“未定義”return x!.toFixed();  // ??
}
  • 繞過類型檢查:當確定一個變量不會是nullundefined,但 TypeScript 編譯器無法確定時,使用 !來繞過類型檢查
  • 避免編譯錯誤:在某些情況下,TypeScript會報錯,因為其認為一個變量可能是nullundefined。使用!可以避免編譯錯誤

模板字符串類型的排列組合

獲得一組規律固定,可由排列組合得到的聯合類型

type A = 'a1' | 'a2';
type B = 'b1' | 'b2';type Products = `${A}-${B}`; // "a1-b1" | "a1-b2" | "a2-b1" | "a2-b2"

實用工具類型

interface A {a: number;b: number;c: number;
}
interface B {c: number;d: number;
}
方法作用示例結果
Partial<Type>構造一個將 Type 的所有屬性設置為可選的類型Partial<A & B>{a?: number, b?: number, c?: number}
Pick<Type, Keys>Type 中選取一組屬性 Keys來構造一個類型Pick<A, 'a'|'c'>{a: number, c: number}
Omit<Type, Keys>Type 中選擇所有屬性然后刪除 Keys來構造一個類型Omit<A, 'a'|'c'>{b: number}
Extract<Type, Union>Type 中提取所有可分配給 Union 的聯合成員來構造一個類型Extract<A|B, B>B

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/87622.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/87622.shtml
英文地址,請注明出處:http://en.pswp.cn/web/87622.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

逐步構建高性能http服務器及聊天室服務器

目錄 如何拿到瀏覽器發來的http請求 如何給瀏覽器發送響應 響應基本原理 給瀏覽器發送一個網頁作為響應 給瀏覽器發送一個圖片作為響應 接下來我們要做什么 完善業務邏輯 瀏覽器如何訪問特定文件 訪問根目錄下的文件 訪問子文件夾下的文件 習慣性目錄結構 GET請求帶…

水下航行器外形分類詳解

在水下航行器的設計領域&#xff0c;外形是影響其性能和功能的關鍵因素之一。根據不同的設計目的和應用場景&#xff0c;水下航行器的外形可以按照多種方式進行分類。 本文將詳細介紹幾種常見的分類方式及其對應的外形特點。 按流體動力布局分類 標準回轉體 外形標準回轉體外…

Ubuntu:Mysql服務器

mariadb與mysql完全兼容&#xff0c;使用時感受不到差別 目錄 1 mariadb的安裝2 啟動mysql3 關閉防火墻4 連接到mysql5 Mysql的配置文件6 Mysql遠程訪問 1 mariadb的安裝 apt install mariadb-server檢查安裝 ls /etc/init.d2 啟動mysql service mysql restart3 關閉防火墻…

使用systemd 監控服務并實現故障自動重啟

一、為什么需要自動重啟&#xff1f; 在生產環境中&#xff0c;服務可能因內存溢出、資源競爭、外部依賴中斷等問題意外崩潰。手動恢復效率低下&#xff0c;而 systemd 的自動重啟機制可在秒級內恢復服務&#xff0c;顯著提升系統可用性。 ?? 二、systemd 自動重啟的核心配置…

在 React 中使用 WebSockets 構建實時聊天應用程序

實時通信已成為現代 Web 應用程序&#xff08;尤其是在聊天應用程序中&#xff09;不可或缺的功能。實時通信提供了一種強大的方法來實現客戶端和服務器之間的實時雙向通信。在本指南中&#xff0c;我們將逐步講解如何使用React WebSockets構建實時聊天應用程序。 先決條件 在…

實驗五-Flask的簡易登錄系統

一、實驗目的和任務 1.掌握Flask框架的基本使用方法 2.理解Web應用的會話管理機制 3.實現用戶認證系統的基本功能 4.學習模板繼承和表單處理技術 要求&#xff1a;請將思考題的答案寫在實驗報告中 二、實驗內容 1.基礎環境搭建&#xff1a;創建項目目錄結構、安裝必要依賴包…

WebSocket類明明注入了Bean,為什么報錯為null

在 WebSocket 類中注入 Bean 看似可行而注入 Bean 報錯為null&#xff0c;通常是由于Spring 的單例管理機制與 WebSocket 多實例創建特性沖突導致的&#xff0c;具體分析如下&#xff1a;原因分析Spring 的單例特性&#xff1a;Spring 默認以單例模式管理 Bean&#xff0c;即一…

Python 爬蟲開發指南:從基礎到實戰

在大數據時代&#xff0c;數據成為了寶貴的資源。Python 爬蟲作為高效獲取網絡數據的工具&#xff0c;受到越來越多開發者的關注。本文將詳細介紹 Python 爬蟲的相關知識&#xff0c;助你快速入門并掌握爬蟲開發的核心要點。 一、Python 爬蟲概述 Python 爬蟲&#xff0c;即網…

99、git 超時問題

報錯&#xff1a; Push failed ssh: connect to host github.com port 22: Connection timed out Could not read from remote repository

CountDownLatch 詳細介紹

CountDownLatch 是 Java 中 java.util.concurrent 包提供的一個同步工具類&#xff0c;用于協調多個線程之間的執行順序。它允許一個或多個線程等待&#xff0c;直到其他線程完成一組操作后繼續執行。CountDownLatch 是一種倒計數鎖存器&#xff0c;通過設置一個初始計數器值&a…

Hadoop之HDFS

Hadoop之HDFS HDFS的Shell操作 啟動Hadoop集群(方便后續測試) [atguigu@hadoop102 ~]$ sbin/start-dfs.sh [atguigu@hadoop102 ~]$ sbin/start-yarn.sh-help:輸出這個命令參數 [atguigu@hadoop102 ~]$ hadoop fs -help rm-ls:顯示目錄信息 [atguigu@hadoop102 ~]$ hadoop …

【1.4 漫畫PostgreSQL高級數據庫及國產數據庫對比】

&#x1f418; 漫畫PostgreSQL高級數據庫及國產數據庫對比 &#x1f468;?&#x1f4bb; 小明&#xff1a;“老王&#xff0c;除了MySQL&#xff0c;還有哪些優秀的關系型數據庫&#xff1f;國產數據庫發展得怎么樣&#xff1f;” &#x1f9d9;?♂? 架構師老王&#xff1a;…

OLT、ONU、ONT、SFU、HGU、ODN,它們是什么?它們之間有什么區別?

我們經常會看到OLT、ONU、ONT、SFU、HGU等設備術語。它們分別是什么?又有什么區別呢? PON組件:OLT、ONU、ONT和ODN 無源光網絡(PON)采用光纖和分路器&#xff0c;以點對多點拓撲將數據從單一源分發到多個用戶。與有源光網絡 (AON)不同&#xff0c;PON 僅在光域中運行&#…

sql USING 簡化 JOIN 操作

在 SQL 中&#xff0c;USING 是一種用于簡化 JOIN 操作的語法糖&#xff0c;它允許你明確指定連接表時所依據的列名。與傳統的 ON 子句相比&#xff0c;USING 提供了更簡潔的語法1. 基本語法與作用table1 JOIN table2 USING (column_name);將 table1 和 table2 中 column_name …

android開發中的 AndroidX 版本的查看 及 constraintLayout的簡單用法

1、查看庫的版本 平常我們經常會用到一些庫&#xff0c;但是不知道是什么版本&#xff0c;也不知道最新的是什么版本&#xff0c;當然最好的就是到官網去查看&#xff0c;或者三方的maven庫。 2、官方地址 AndroidX 版本 | Jetpack | Android Developers 3、比如我們來…

oracle鎖表,oracle解鎖表,oracle用戶連接數

一、查看被鎖的表 select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo.locked_mode from v$locked_object lo, dba_objects ao, v$session sess where ao.object_id lo.object_id and lo.session_id sess.sid; 二、解鎖表語句 alter …

3D可視化:開啟多維洞察新時代

3D可視化技術以一種前所未有的方式&#xff0c;將數據、模型與現實世界緊密相連&#xff0c;為人們帶來了沉浸式、交互式的全新體驗&#xff0c;徹底革新了信息的呈現與理解方式。一、3D可視化的技術原理從技術本質來看&#xff0c;3D可視化基于一系列復雜而精妙的原理。通過數…

List中的對象進行排序處理

以下是使用 Java Stream 對對象列表按 id 和 age 排序的完整示例&#xff0c;包含升序和降序兩種場景&#xff1a; 1. 定義測試對象類 Getter Setter public class Person {private int id;private int age; }2. 排序實現代碼 import java.util.*; import java.util.stream.…

秋招Day14 - Redis - 底層結構

Redis都有哪些底層數據結構&#xff1f; 有八種核心的底層數據結構。 SDS Redis自己實現的動態字符串&#xff0c;SDS結構中直接存儲了已使用的字符數組長度len和未使用的字符數組長度free&#xff0c;所以獲取長度的時間復雜度是O(1)&#xff0c;還支持動態擴容&#xff0c…

使用Mac自帶的圖像捕捉導出 iPhone 相冊

用 數據線 將 iPhone 連接到 Mac必須是數據線,有些充電線插上去后無法識別到iphone在 iPhone 上點擊“信任此電腦”在 Mac 上打開應用&#xff1a;快速方式&#xff1a;按 Command Space 打開 Spotlight&#xff0c;輸入 圖像捕捉 或 Image Capture&#xff0c;回車或者從 /系…