我遇到這樣一種情況,我有一個類實例的PropertiesObject
或Structure
,然后需要在運行時由一個函數將Constructor
和Structure
轉換為實際實例。但它允許我傳入一個不遵循簽名的構造函數。見下表:
type PropertyNames<T> = {
[K in keyof T]: T[K] extends Function ? never : K;
}[keyof T];
type Struct<T> = Pick<T, PropertyNames<T>>;
type Constructor<T> = new (struct: Struct<T>) => T;
class MagicMonkey {
age: number;
name: string;
fly() {
}
}
function createObjectIntance<T>(Constructor: Constructor<T>, struct: Struct<T>): T {
return new Constructor(struct);
}
const jack: MagicMonkey = createObjectIntance(MagicMonkey, { name: 'jack', age: 1000})
console.log(jack)
MagicMonkey
沒有接受參數Struct<MagicMonkey>
的構造函數。我是遺漏了什么還是這是一個錯誤?
它確實迫使我在函數中編寫new Constructor(struct);
,而不僅僅是new Constructor();
。所以它在某種程度上起作用了。
問題是您正在鍵入
createObjectInstance
以接受一個具有non-function類屬性名的對象。不是構造函數參數數組。MagicMonkey
構造函數的類型是() => MagicMonkey
。鍵入所需的createObjectInstance
,因為第一個數組是{ new (struct: Struct<MagicMonkey>): MagicMonkey }
。它們是完全可分配的:playground link
如果您將源函數看作一個函數,只需丟棄它可能獲得的任何參數并返回我們所需的類型,那么它可能有助于理解賦值是完全類型安全的一般思想。
如果您想鍵入
createObjectInstance
,以便構造函數應該拒絕不兼容的參數,您應該這樣做:playground link