在 属性 中推断通用类型(就像在函数中一样)以进行正确的类型检查
Infer generic type in property (like in a function) for proper type checking
我正在尝试让编译器推断和检查泛型 属性 中的类型。
特别是我有:
type Args<T, O extends object> = {
instance: O,
key: { [K in keyof O]: T extends O[K] ? K : never }[keyof O]
};
class C<T> {
public fn<O extends object>(args: Args<T, O>): void { }
}
Args
是一个对象及其键之一 k
,因此 T
类型的内容可以分配给 k
。
class 可以像这样使用:
type Test = { a: string, b: number };
let test: Test = { a: "", b: 2 };
let c = new C<string>();
c.fn({ instance: test, key: "a" }); // works, as expected
c.fn({ instance: test, key: "b" }); // error, as expected
这很好,因为推断类型参数 O
,检查 key
的类型,并在输入时建议 key
的所有可能性。
现在我想使用一个可以与 C<T>.fn
一起使用的 Args
对象作为 属性 在其他一些 classes 中(用于注入目的),其中O
的类型还未知。
但是类型检查失败 any
:
interface I<T> {
args: Args<T, any>;
}
let i: I<string>;
i = { args: { instance: test, key: "b" } }; // no error
我尝试改用 lambda:
interface I2<T> {
args: <O extends object>() => Args<T, O>;
}
let i2: I2<string>;
i2 = { args: () => ({ instance: test, key: "a" }) }; //Type 'Test' is not assignable to type 'O'. ???
c.fn(i.args);
我不明白为什么会出现类型错误。
如何确保推断类型并检查接口的 属性 就像它适用于通用函数一样?
因此,由于这是不可能的,因此一种实用的方法是使用 setter 或强制执行类型约束的工厂。例如:
type Thing<T, A> = {
a: A,
b: SomeTypeDependingoOn<A>
};
class Factory<T> {
public getThing<A, B extends SomeTypeDependingoOn<A>>(a: A, b: B): Thing<T, A>{
return { a: a, b: b };
}
}
let thing: Thing<string, any>;
thing = new Factory<string>().getThing(...); // type checking
我正在尝试让编译器推断和检查泛型 属性 中的类型。 特别是我有:
type Args<T, O extends object> = {
instance: O,
key: { [K in keyof O]: T extends O[K] ? K : never }[keyof O]
};
class C<T> {
public fn<O extends object>(args: Args<T, O>): void { }
}
Args
是一个对象及其键之一 k
,因此 T
类型的内容可以分配给 k
。
class 可以像这样使用:
type Test = { a: string, b: number };
let test: Test = { a: "", b: 2 };
let c = new C<string>();
c.fn({ instance: test, key: "a" }); // works, as expected
c.fn({ instance: test, key: "b" }); // error, as expected
这很好,因为推断类型参数 O
,检查 key
的类型,并在输入时建议 key
的所有可能性。
现在我想使用一个可以与 C<T>.fn
一起使用的 Args
对象作为 属性 在其他一些 classes 中(用于注入目的),其中O
的类型还未知。
但是类型检查失败 any
:
interface I<T> {
args: Args<T, any>;
}
let i: I<string>;
i = { args: { instance: test, key: "b" } }; // no error
我尝试改用 lambda:
interface I2<T> {
args: <O extends object>() => Args<T, O>;
}
let i2: I2<string>;
i2 = { args: () => ({ instance: test, key: "a" }) }; //Type 'Test' is not assignable to type 'O'. ???
c.fn(i.args);
我不明白为什么会出现类型错误。
如何确保推断类型并检查接口的 属性 就像它适用于通用函数一样?
因此,由于这是不可能的,因此一种实用的方法是使用 setter 或强制执行类型约束的工厂。例如:
type Thing<T, A> = {
a: A,
b: SomeTypeDependingoOn<A>
};
class Factory<T> {
public getThing<A, B extends SomeTypeDependingoOn<A>>(a: A, b: B): Thing<T, A>{
return { a: a, b: b };
}
}
let thing: Thing<string, any>;
thing = new Factory<string>().getThing(...); // type checking