让我们看看我想构建一个函数:
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
可以是什么,在这种情况下是A
或B
.
这可能吗?
您可以通过缩小泛型类型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
不限于A
或B
;T
也可以PossibleObjects
本身。我不认为有办法禁止它,但你应该意识到这一点。