Я пытаюсь сделать вывод компилятора и проверить типы в универсальном свойстве.В частности, у меня есть:
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
.Класс можно использовать следующим образом:
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
.
Теперь я хочу использовать объект Args
, который можно использовать с C<T>.fn
в качестве свойства в некоторых других классах (для целей внедрения), где тип O
еще не известен.Однако проверка типа завершается неудачно с any
:
interface I<T> {
args: Args<T, any>;
}
let i: I<string>;
i = { args: { instance: test, key: "b" } }; // no error
Я попытался использовать лямбду вместо:
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);
Я не понимаю, почему возникает ошибка типа.
Как вы можете убедиться, что типы выводятся и проверяются для свойства интерфейса, как это работает для универсальной функции?