我有一個用 javascript 撰寫的函式:
function myFunction(param1, param2) {
//do stuff
}
我將如何撰寫打字稿宣告檔案以確保 param1 是包含 {} 的字串,而 param2 是數字、字串或數字/字串陣列?
例如:
param 1 = "The boat is {}"
param 2 = "yellow"
示例 2:
param1: "There are {} out of {} students here"
param2: [20, 30]
Param2 應該具有與“{}”數量相對應的元素數量。Param1 必須至少包含 1 個 {}。回傳型別應該是一個字串
uj5u.com熱心網友回復:
如果我真的想嘗試在型別級別強制執行這些約束,我會采用以下方法:
declare function myFunction<S extends `${string}{}${string}`>(
param1: S, param2: Param2<S>
): string;
type Param2<S extends string, A extends any[] = []> =
S extends `${string}{}${infer R}` ?
Param2<R, [...A, number | string]> :
A | (A extends [any] ? A[0] : never);
因此,引數的型別myFunction是泛型的,它被限制為“模式模板文字型別”(在microsoft/TypeScript#40598中實作和定義),它對應于所有已知包含至少一次出現的字串的字串. 那么 的型別是,其意圖是表示對應的正確型別。并回傳一個.Sparam1`${string}{}${string}`"{}"param2Param2<S>param2param1myFunction()string
該Param2<S>型別是一種尾遞回條件型別,它基本上計算"{}"出現的次數S并產生一個恰好長度的元組型別,其元素都是string | number(一個接受一個或一個值的聯合型別)......而且,如果那個長度是,它也接受一個裸露的.stringnumber1string | number
它的作業方式是將結果累積在一個元組型別引數A中,該引數以空元組開始[]。如果其中S有 a "{}",那么我們計算Param2<R, [...A, number | string]>哪個是作用于第R一個之后的字串部分的相同操作,并且附加"{}"了另一個元素(通過可變元組型別)。如果里面沒有,那么我們就完成了,我們可以回傳累積的......如果是長度,那么我們也產生一個與的聯合。number | stringAS"{}"AA1Anumber | string
讓我們測驗一下。以下呼叫編譯沒有錯誤:
myFunction("The boat is {}", "yellow");
myFunction("The boat is {}", ["yellow"]);
myFunction("There are {} out of {} students here", [20, 30]);
myFunction("There are {} out of {} students here and the boat is {}", [20, 30, "yellow"]);
而以下呼叫都至少有一個錯誤:
myFunction("The boat is yellow", []) // error!
// ------> ~~~~~~~~~~~~~~~~~~~~
// Argument of type '"The boat is yellow"' is not assignable to
// parameter of type '`${string}{}${string}`'
myFunction("The boat is {}", ["yellow", "green"]); // error!
// -----------------------------------> ~~~~~~~
// Type 'string' is not assignable to type 'undefined'.
myFunction("There are {} out of {} students here", 20); // error!
// ----------------------------------------------> ~~
// Argument of type 'number' is not assignable to
// parameter of type '[string | number, string | number]'
myFunction("There are {} out of {} students here", [20, 30, 40]); // error!
// ----------------------------------------------> ~~~~~~~~~~~~
// Source has 3 element(s) but target allows only 2
這一切都說得通。在第一種情況下,它param1甚至沒有一個"{}",所以這是一個錯誤。在其余情況下,param2元素太多或太少。
所以你去吧,這就是你所要求的。請注意,這可能比它的價值更麻煩,具體取決于您的用例。這是一個相當復雜的輸入,它需要編譯器跟蹤您傳入的值的確切文字型別param1for 。TypeScript 通常會采用字串文字并將其型別擴展到只是string因為啟發式地講人們通常不關心文字型別。例如:
let someString = "The boat is {}";
// let someString: string;
在這里我使用let了 ,它提示編譯器擴展變數以string假設我以后可能會重新分配它。然后你寫這個并得到一個錯誤:
myFunction(someString, "yellow"); // error!
// Argument of type 'string' is not assignable to
// parameter of type '`${string}{}${string}`'
盡管這在運行時會很好,但編譯器會抱怨;它已經忘記了其中的價值someString,因此不能確定它有什么價值"{}"。也許這對您的用例來說很好,但您應該意識到它有可能使用起來很煩人。
Playground 代碼鏈接
uj5u.com熱心網友回復:
這將定義一個接受字串和 int 陣列作為引數的打字稿函式:
myFunction(param1: string, param2: int[]) {
//do stuff
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/515577.html
標籤:打字稿
上一篇:Angular:httpGET方法在呼叫httpPOST后不起作用,但是當我用setTimeout()方法封裝GET方法時它起作用。為什么?
下一篇:如何在此組件設定中推斷型別?
