【发布时间】:2019-10-27 10:33:58
【问题描述】:
为了好玩,我想看看我是否可以想出一种方法,只使用类型,它会强制类中的所有函数成为一个一元函数,只要该对象符合指定的接口(在这种情况下,我想确保提供 ContextObj 作为参数)
我是这样尝试的:
interface BaseContext {}
interface SomeContext { foo: 'lish'; };
interface ContextObj<T> { context: T }
// a unary function that takes an argument that conforms to the ContextObj interface
// and returns a value of type U
type ContextFn<T, U> = (x: ContextObj<T>) => U;
// a type to represent any function
type AnyFunction = (...args: any[]) => any;
// we use mapped types and conditional types here to determine if
// T[K], the value of the property K on type T, is a function
// if it's not a function we return the T[K] unaltered
// if it is a function we make sure it conforms to our ContextFn type
// otherwise we return never which I was hoping would result in an error
type ContextService<T, U extends BaseContext> = {
[K in keyof T]: T[K] extends AnyFunction
? T[K] extends ContextFn<U, ReturnType<T[K]>>
? T[K]
: never
: T[K]
};
class BarService implements ContextService<BarService, SomeContext> {
test:string = 'test';
// expected error: not assignable to type never
updateBar(): string {
return '';
}
}
事实证明这并没有按预期工作,因为它是 TypeScript 的限制(或功能?):https://github.com/Microsoft/TypeScript/wiki/FAQ#why-are-functions-with-fewer-parameters-assignable-to-functions-that-take-more-parameters
我很好奇是否有办法在类或接口级别做这样的事情(强制方法参数与特定类型签名匹配)?是否可以通过装饰器在单个方法级别完成(此时授予您最好使用适当的类型签名)。
只是测试极限:)
【问题讨论】:
标签: typescript typescript-typings typescript-generics