是否可以设置类型参数的可能类型?



让我们看看我想构建一个函数:

type A = {
foo: boolean
};
type B = {
bar: boolean
}
type PossibleObjects = A | B
type Object <T> = {
[key in keyof T]?: boolean
}
const fn = <
T //:PossibleObjects
>(object: Object<T>) => object;

尽管这个函数没有任何用处,但解释一下我想要的东西是很好的。我想控制T可以是什么,在这种情况下是AB.

这可能吗?

您可以通过缩小泛型类型T来扩展可能的对象来实现这一点。

type A = { foo: boolean };
type B = { bar: boolean };
type PossibleObjects = A | B
type SomeObject <T> = {  // Renamed to "SomeObject" since "Object" is already a default type
[key in keyof T]?: boolean
}
const fn = <T extends PossibleObjects> // This makes T a subtype of PossibleObjects
(object: SomeObject<T>) => object;
fn({ foo: true });  // Works
fn({ bar: true });  // Works
fn({ baz: true });  // Error: Argument of type '{ baz: boolean; }' is not assignable to parameter of type 'SomeObject<A> | SomeObject<B>'.

如果SomeObject类型只能(而不仅仅是在fn函数中(指定PossibleObjects类型中的键,则可能还需要在SomeObject类型上执行此操作。

type A = {
foo: boolean
};
type B = {
bar: boolean
}
type PossibleObjects = A | B
type SomeObject <T extends PossibleObjects> = { // Adds the type constraint here
[key in keyof T]?: boolean
}
// Now the following works
const fn = <T extends PossibleObjects>(object: SomeObject<T>) => object;
// But this one will NOT be valid anymore 
const fn2 = <T>(object: SomeObject<T>) => object; 
// Error:                          ^
// Type 'T' does not satisfy the constraint 'PossibleObjects'.

使用管道 (|( 运算符提供不同的类型:

function fn(arg: A | B): any {
// code
}

关键字extends设置类型参数的上限。这适用于类型声明和函数声明。

type SomeObject<T extends PossibleObjects> = {
[key in keyof T]?: boolean
}
const fn = <T extends PossibleObjects>(obj: SomeObject<T>) => obj;

请注意,此处的T不限于AB;T也可以PossibleObjects本身。我不认为有办法禁止它,但你应该意识到这一点。

最新更新