[英]Expected 3 type arguments but got 1 but it should infer 2 types
我想知道如何正確推斷我的函數的第二個和第三個模板
假設一個簡單的界面
interface ISome {
a: string;
b?: {
c: string;
};
}
關注作品
function pathBuilder<
K1 extends keyof ISome,
K2 extends keyof NonNullable<ISome[K1]>>(p: K1, p2?: K2) {
let res = String(p);
if (p2) { res += "." + p2; }
return res;
}
const pathTest = pathBuilder("b", "c"); // ---> "b.c" and intellisense works on parameters
但我需要通過指定另一種類型來概括該函數以使其工作(我不想傳遞對象實例來指定類型)
所以,以下不起作用
function pathBuilder<
T,
K1 extends keyof T,
K2 extends keyof NonNullable<T[K1]>>(p: K1, p2?: K2) {
let res = String(p);
if (p2) { res += "." + p2; }
return res;
}
const pathTest = pathBuilder<ISome>("b", "c"); // ERROR: Expected 3 type arguments, but got 1.ts(2558)
似乎函數的第 2 個和第 3 個模板參數不能從第一個參數推斷出來,但它應該是因為在第一種情況下,當我直接指定類型 T=ISome 時它起作用了。
我不確定是否有一些語言關鍵字可以使其工作,但模板應該完全適用:指定未知類型。
編輯
實際上我找到了這種方式,但需要額外的編碼,如果可能的話我會避免
function pathBuilder<T>() {
return <
K1 extends keyof T,
K2 extends keyof NonNullable<T[K1]>>(p: K1, p2?: K2) => {
let res = String(p);
if (p2) { res += "." + p2; }
return res;
};
}
const pathTest = pathBuilder<ISome>()("b", "c");
從 TS3.4 開始,沒有部分類型參數推斷。 要么讓編譯器嘗試推斷所有類型參數,要么指定所有類型參數。 (嗯,有默認類型參數,但這並沒有給你你想要的:你想推斷你遺漏的類型參數,而不是為它們分配默認類型)。 已經有幾項提議來解決這個問題,但到目前為止,沒有一個得到完全批准。
因此,目前只有解決方法。 我能想到的兩個是使用虛擬函數參數或使用currying 。
虛擬參數版本:
function pathBuilderDummy<
T,
K1 extends keyof T,
K2 extends keyof NonNullable<T[K1]>>(dummy: T, p: K1, p2?: K2) {
let res = String(p);
if (p2) { res += "." + p2; }
return res;
}
const pathDummyTest = pathBuilderDummy(null! as ISome, "b", "c");
在這里,我們正在做你說你不想做的事情……傳入一個T
類型的參數。 但由於它只是一個虛擬參數而不是在運行時使用,所以它只與類型系統認為它是什么有關。 您傳入的值的實際類型無關緊要。 因此,您可以將其傳遞為null
並使用類型斷言來選擇T
。
咖喱函數解決方案:
const pathBuilderCurry =
<T>() => <
K1 extends keyof T,
K2 extends keyof NonNullable<T[K1]>>(p: K1, p2?: K2) => {
let res = String(p);
if (p2) { res += "." + p2; }
return res;
}
const pathCurryTest = pathBuilderCurry<ISome>()("b", "c")
在這里,您正在返回一個返回另一個函數的函數。 第一個函數不接受任何值參數,但它接受您要指定的一個類型參數。 然后它返回一個函數,其中指定了T
但推斷了其他類型參數。
這兩種解決方案都不是完美的,但它們是我們目前能做的最好的。 希望有所幫助; 祝你好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.