在属性中推断泛型类型(如在函数中)以进行正确的类型检查

问题描述 投票:-1回答:1

我试图让编译器推断并检查泛型属性中的类型。特别是我有:

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

我尝试使用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);

我不明白为什么会出现类型错误。

如何确保类型被推断和检查接口的属性,就像它适用于通用函数一样?

typescript type-inference typescript-generics
1个回答
0
投票

因此,由于这是不可能的,所以实际的方法是使用强制类型约束的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
© www.soinside.com 2019 - 2024. All rights reserved.