我正在嘗試構建一個通用函式,以確保在初始化時設定類的特定屬性。(通常我只是通過使引數成為必需的來做到這一點,但有時當您使用動態資料時,這并不總是可能的!)
export const requireParams = (cls: AnyClass, requiredParams: string[]) => {
if (!requiredParams) {
return;
}
const missingParams = requiredParams.filter(
(param) => cls?.[param] === undefined || cls?.[param] === null || cls?.[param] === NaN
);
if (missingParams.length) {
throw new Error(`Missing required params: ${missingParams.join(", ")}`);
}
};
然后我會像這樣使用它:
class Foo {
constructor(public readonly food: string) {
requireParams(this, ['food']);
}
}
AnyClass這是理論上的——雖然我可以requireParams通用并總是傳入clsby的型別<T>(cls: AnyClass<T>),但這有點迂腐,在我的大腦中,你應該能夠從cls?的型別推斷 T
我嘗試了一些古怪的事情,例如:
type AnyClass<T> = T extends new (...args: any[]) => infer R ? R : never;
(但總是回傳 T as never)
我嘗試了許多其他瘋狂的想法來嘗試從實體中推斷 T,例如:
type GenericOf<T> = T extends new (...args: any) => InstanceType<infer X> ? X : T;
type AnyClass<T = any> = GenericOf<T extends new (...args: any) => infer X ? X : never>;
但它仍然回到 T being 的默認值any,因此假設 T is unknown。
(這最終是因為我不知道自己在做什么)。
似乎我也嚴重過度考慮了這一點 - 也許我需要輸入requireParams<T>并給 T 一個默認值(并強制它是一個類?)
這可能嗎?如果是這樣,怎么做?還是我成為這個問題的受害者?
uj5u.com熱心網友回復:
將問題簡單化為T直接使用似乎(幾乎)可以解決您的問題。
export const requireParams = <T,>(instance: T, requiredParams: (keyof T)[]) => {
if (!requiredParams) {
return;
}
const missingParams = requiredParams.filter(
(param) => instance?.[param] === undefined || instance?.[param] === null || parseInt(instance?.[param]?.toString()) === NaN
);
if (missingParams.length) {
throw new Error(`Missing required params: ${missingParams.join(", ")}`);
}
};
操場
但是你也想約束T成為一個類實體。AFAIK,型別系統中沒有任何東西可以將類實體與任何其他物件區分開來。我剛剛嘗試了您的評論,但它似乎對我不起作用:/
export type AnyClass = new <T extends { constructor: Function }>(...args: (keyof T)[]) => T;
const requireParams = <T extends InstanceType<AnyClass>>(
instance: T,
requiredParams?: (keyof T)[]
) => {
// ...
};
class Foo {
food: string;
constructor(food: string) {
this.food = food;
requireParams(this, ["food", "bar"]);
// ~~~~~
}
}
requireParams({}, ["food", "bar"]);
// ~~~~~~ ~~~~~
// This should complain on passing an empty {}, but doesn't.
// At least its params are caught as invalid though.
interface TastySnack {
snacks: string;
}
requireParams({ snacks: "crisps" } as TastySnack, ["snacks", "bar"]);
// ~~~~~
操場
OP的游樂場
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/523366.html
標籤:打字稿仿制药打字稿泛型
上一篇:Scala型別橡皮擦
下一篇:無法覆寫接受泛型內部類引數的方法
