」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Beyond Type Safety:TypeScript運行時選擇器深度解析

Beyond Type Safety:TypeScript運行時選擇器深度解析

發佈於2025-03-12
瀏覽:182

[2

Beyond Type Safety: making TypeScript smarter by Building a Runtime Picker嘿,在开始之前,让我澄清一下:虽然我会谈论我的软件包,但

ts-runtime-picker

,这不是促销文章。我只是在分享自己的经验以及在构建之前所经历的旅程。 (,但是嘿,如果您很好奇,这是指向软件包的链接?)。

typescript如何使我成为一个新的想法(和一个软件包) 让我们倒回去。因此,我已经使用TypeScript了一段时间了。我不会称自己为打字稿专业人士,但是我已经建立了一些大型项目,并在我的公司中使用了它。您知道,通常的“ Hello World”项目,一些更复杂的项目,当然,还有相当多的Google旅行来弄清楚“这个错误意味着什么?”或“如何再次从接口中挑选字段?” (您明白了。?)

有一天,我在使用Firebase Cloud功能时遇到了一个问题。我在
createuser

端点上,编写我的验证逻辑,修剪数据并处理常规的crud请求疯狂。一切都流畅地移动,直到我从以前的开发人员那里遇到这一代码:

...我的内部打字稿Pro在尖叫。 ?

我的意思是,这是一个巨大的危险信号。正确的?直接插入未经过滤的用户数据是有风险的 - 如果请求数据缺少某些验证,我们最终将不需要的字段插入数据库中?不好。
我迅速删除了代码,但是,我冻结了一秒钟。 ?我盯着屏幕思考:“坚持不懈,如果我只是将请求分配给用户界面类型,那么打字稿会阻止我做这样的事情吗?这是否解决问题吗?” (提示我的IDE有希望的一眼,等待红色的线条出现。)

firebase.collection("users").add(request.data.user);
魔术。这只是一张编译时间检查,对吗?它在运行时不存在。 Typescript是用于类型安全的掩码,但是当代码运行时,它实际上并没有强制执行任何操作。它不是

阻止在运行时插入额外的字段。

因此,我打电话给我的一个队友,问:“嘿,如果我们有一个名为字母的对象,并在字母内使用所有字母,并且创建一个只允许字母'a''''和'b'的界面,当我们将字母施放到该界面时会发生什么? //对所有字母字母的对象 const alphabets = { 答:“苹果”, B:“香蕉”, C:“樱桃”, D:“日期”, E:“茄子”, F:“无花果”, // ...一直到Z }; //仅允许“ A”和“ B”的接口 唯一接口twoletters { 答:字符串; B:字符串; } //将字母施放到只有woletters const FilledAlphabets = Alphabets仅为woletters; console.log(filledalphabets);

没有错过任何节奏,我的队友说:“哈哈,好吧,您仍然会收到所有字母字母,因为Typescript无法真正在运行时停止。”

该死。我就知道。我正受希望的效果 -

,Typescript可以神奇地阻止我在运行时犯错误。 ? ,但是,它打了我:如果打字稿可以在运行时执行此操作怎么办?如果我们可以将对象施放到特定的接口并使Typescript 自动剥离接口中未定义的任何属性怎么办?


可以解决我的问题。

// Object with all alphabet letters
const alphabets = {
  a: 'Apple',
  b: 'Banana',
  c: 'Cherry',
  d: 'Date',
  e: 'Eggplant',
  f: 'Fig',
  // ... all the way to z
};

// Interface that only allows 'a' and 'b'
interface OnlyTwoLetters {
  a: string;
  b: string;
}

// Casting alphabets to OnlyTwoLetters
const filteredAlphabets = alphabets as OnlyTwoLetters;

console.log(filteredAlphabets);

TS-Runtime-picker的诞生

因此,在这个灯泡的时刻,我想:“为什么不将其实现呢?”如果我可以将请求施放到用户界面,那么TypeScript可以自动帮助我删除任何额外的属性,从而使对象安全地插入firebase中。 ?

和那样,

ts-runtime-picker 的想法是诞生的。目标很简单:创建一个软件包,该软件包可以根据特定接口中定义的字段来滤除对象的不需要属性。 最好的部分?这将使我免于手动验证和过滤字段的过滤。几天已经一去不复返了:

const filleddata = { 名称:requestData.name, 年龄:requestData.age, }; firebase.Collection(“用户”)。add(FilledData); //更多的工作,更有趣。


的工作方式:让打字稿完成其作业

ts-runtime-picker

,整个过程都是自动化的。您可以将对象施放到接口,并且软件包将确保仅保留接口中定义的属性。这是它在行动中的工作方式:

之前:手动验证

接口用户{ 名称:字符串; 年龄:数字; } const requestData = {名称:'John',年龄:30,地址:'123 Street'}; //手动检查并删除不需要的字段: const FilterData = { 名称:requestData.name, 年龄:requestData.age, }; firebase.Collection('用户')。add(FilledData); //不是很优雅。


const filteredData = {
  name: requestData.name,
  age: requestData.age,
};

firebase.collection("users").add(filteredData);  // More work, less fun.

最好的部分?此代码默认情况下是

。无需手动检查或对象操纵。 TS-runtime-picker通过过滤用户界面中不存在的所有字段来自动为您处理它。您只需关注核心逻辑而不担心意外插入。 ?

的懒惰力量(以及它如何导致创新)

因此,您可能想知道:“这是纯粹的懒惰吗?”为此,我说:

的渴望使事情变得更容易可能是创新的推动力。 实际上,尽管最初的“懒惰”,但我花了8个小时

构建软件包。是的,是的。 ?
// Object with all alphabet letters
const alphabets = {
  a: 'Apple',
  b: 'Banana',
  c: 'Cherry',
  d: 'Date',
  e: 'Eggplant',
  f: 'Fig',
  // ... all the way to z
};

// Interface that only allows 'a' and 'b'
interface OnlyTwoLetters {
  a: string;
  b: string;
}

// Casting alphabets to OnlyTwoLetters
const filteredAlphabets = alphabets as OnlyTwoLetters;

console.log(filteredAlphabets);

,但有时就是这样。 “需求诞生了发明”,这需要避免乏味的重复检查导致一种新的解决方案,这最终使我的生活(并希望许多其他人的生活)变得容易得多。

因此,虽然我可以懒惰,但需要解决问题的问题,这引起了 ts-runtime-picker

。有时,
import { pick } from 'ts-runtime-picker';

interface User {
  name: string;
  age: number;
}

const requestData = { name: 'John', age: 30, address: '123 Street' };

// Automatically filters out non-existent properties:
const safeData = pick(requestData, User);

firebase.collection('users').add(safeData);  // Much cleaner!

结论


,这就是 ts-runtime-picker package的故事。从打字稿挫败到创建解决真正问题的工具的旅程。该软件包是我帮助打字稿用户充分利用类型安全的方式 - 不仅在开发期间,而且在运行时。

如果您厌倦了手动过滤字段或担心不需要的数据潜入,请给出

ts-runtime-picker 。这是不必担心的一件事,它使使用Typescript的工作越聪明。 ?

版本聲明 本文轉載於:https://dev.to/hichemtab-tech/beyond-type-safety-making-typescript-smarter-by-building-a-runtime-picker-26d5?1如有侵犯,請聯繫[email protected]刪除
最新教學 更多>
  • 如何使用Regex在PHP中有效地提取括號內的文本
    如何使用Regex在PHP中有效地提取括號內的文本
    php:在括號內提取文本在處理括號內的文本時,找到最有效的解決方案是必不可少的。一種方法是利用PHP的字符串操作函數,如下所示: 作為替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式來搜索特...
    程式設計 發佈於2025-05-19
  • CSS可以根據任何屬性值來定位HTML元素嗎?
    CSS可以根據任何屬性值來定位HTML元素嗎?
    靶向html元素,在CSS 中使用任何屬性值,在CSS中,可以基於特定屬性(如下所示)基於特定屬性的基於特定屬性的emants目標元素: 字體家庭:康斯拉斯(Consolas); } 但是,出現一個常見的問題:元素可以根據任何屬性值而定位嗎?本文探討了此主題。 的目標元素有任何任何屬性值,...
    程式設計 發佈於2025-05-19
  • 為什麼PYTZ最初顯示出意外的時區偏移?
    為什麼PYTZ最初顯示出意外的時區偏移?
    與pytz 最初從pytz獲得特定的偏移。例如,亞洲/hong_kong最初顯示一個七個小時37分鐘的偏移: 差異源利用本地化將時區分配給日期,使用了適當的時區名稱和偏移量。但是,直接使用DateTime構造器分配時區不允許進行正確的調整。 example pytz.timezone(&#...
    程式設計 發佈於2025-05-19
  • 如何在鼠標單擊時編程選擇DIV中的所有文本?
    如何在鼠標單擊時編程選擇DIV中的所有文本?
    在鼠標上選擇div文本單擊帶有文本內容,用戶如何使用單個鼠標單擊單擊div中的整個文本?這允許用戶輕鬆拖放所選的文本或直接複製它。 在單個鼠標上單擊的div元素中選擇文本,您可以使用以下Javascript函數: function selecttext(canduterid){ if(d...
    程式設計 發佈於2025-05-19
  • 如何避免Go語言切片時的內存洩漏?
    如何避免Go語言切片時的內存洩漏?
    ,a [j:] ...雖然通常有效,但如果使用指針,可能會導致內存洩漏。這是因為原始的備份陣列保持完整,這意味著新切片外部指針引用的任何對象仍然可能佔據內存。 copy(a [i:] 對於k,n:= len(a)-j i,len(a); k
    程式設計 發佈於2025-05-19
  • C++成員函數指針正確傳遞方法
    C++成員函數指針正確傳遞方法
    如何將成員函數置於c 的函數時,接受成員函數指針的函數時,必須同時提供對象的指針,並提供指針和指針到函數。需要具有一定簽名的功能指針。要通過成員函數,您需要同時提供對象指針(此)和成員函數指針。這可以通過修改Menubutton :: SetButton()(如下所示:[&& && && &&華)...
    程式設計 發佈於2025-05-19
  • 用戶本地時間格式及時區偏移顯示指南
    用戶本地時間格式及時區偏移顯示指南
    在用戶的語言環境格式中顯示日期/時間,並使用時間偏移在向最終用戶展示日期和時間時,以其localzone and格式顯示它們至關重要。這確保了不同地理位置的清晰度和無縫用戶體驗。以下是使用JavaScript實現此目的的方法。 方法:推薦方法是處理客戶端的Javascript中的日期/時間格式化和...
    程式設計 發佈於2025-05-19
  • 在Python中如何創建動態變量?
    在Python中如何創建動態變量?
    在Python 中,動態創建變量的功能可以是一種強大的工具,尤其是在使用複雜的數據結構或算法時,Dynamic Variable Creation的動態變量創建。 Python提供了幾種創造性的方法來實現這一目標。 利用dictionaries 一種有效的方法是利用字典。字典允許您動態創建密鑰並...
    程式設計 發佈於2025-05-19
  • 如何使用不同數量列的聯合數據庫表?
    如何使用不同數量列的聯合數據庫表?
    合併列數不同的表 當嘗試合併列數不同的數據庫表時,可能會遇到挑戰。一種直接的方法是在列數較少的表中,為缺失的列追加空值。 例如,考慮兩個表,表 A 和表 B,其中表 A 的列數多於表 B。為了合併這些表,同時處理表 B 中缺失的列,請按照以下步驟操作: 確定表 B 中缺失的列,並將它們添加到表的...
    程式設計 發佈於2025-05-19
  • 您如何在Laravel Blade模板中定義變量?
    您如何在Laravel Blade模板中定義變量?
    在Laravel Blade模板中使用Elegance 在blade模板中如何分配變量對於存儲以後使用的數據至關重要。在使用“ {{}}”分配變量的同時,它可能並不總是最優雅的解決方案。 幸運的是,Blade通過@php Directive提供了更優雅的方法: $ old_section =...
    程式設計 發佈於2025-05-19
  • 如何同步迭代並從PHP中的兩個等級陣列打印值?
    如何同步迭代並從PHP中的兩個等級陣列打印值?
    同步的迭代和打印值來自相同大小的兩個數組使用兩個數組相等大小的selectbox時,一個包含country代碼的數組,另一個包含鄉村代碼,另一個包含其相應名稱的數組,可能會因不當提供了exply for for for the uncore for the forsion for for ytry...
    程式設計 發佈於2025-05-19
  • Spark DataFrame添加常量列的妙招
    Spark DataFrame添加常量列的妙招
    在Spark Dataframe ,將常數列添加到Spark DataFrame,該列具有適用於所有行的任意值的Spark DataFrame,可以通過多種方式實現。使用文字值(SPARK 1.3)在嘗試提供直接值時,用於此問題時,旨在為此目的的column方法可能會導致錯誤。 df.withCo...
    程式設計 發佈於2025-05-19
  • 如何正確使用與PDO參數的查詢一樣?
    如何正確使用與PDO參數的查詢一樣?
    在pdo 中使用類似QUERIES在PDO中的Queries時,您可能會遇到類似疑問中描述的問題:此查詢也可能不會返回結果,即使$ var1和$ var2包含有效的搜索詞。錯誤在於不正確包含%符號。 通過將變量包含在$ params數組中的%符號中,您確保將%字符正確替換到查詢中。沒有此修改,PD...
    程式設計 發佈於2025-05-19
  • Java為何無法創建泛型數組?
    Java為何無法創建泛型數組?
    通用陣列創建錯誤 arrayList [2]; JAVA報告了“通用數組創建”錯誤。為什麼不允許這樣做? 答案:Create an Auxiliary Class:public static ArrayList<myObject>[] a = new ArrayList<my...
    程式設計 發佈於2025-05-19
  • 如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    為有效的slug生成首先,該函數用指定的分隔符替換所有非字母或數字字符。此步驟可確保slug遵守URL慣例。隨後,它採用ICONV函數將文本簡化為us-ascii兼容格式,從而允許更廣泛的字符集合兼容性。 接下來,該函數使用正則表達式刪除了不需要的字符,例如特殊字符和空格。此步驟可確保slug僅包...
    程式設計 發佈於2025-05-19

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3