我有此代码:
const baseUpstreamImpl = (
client: IClient,
): ProtocolExtension<
{
foobar: (buff: Buffer) => Promise<string>;
}
> => ({
name: 'base upstream impl',
type: 'upstream',
messageCreators: {
foobar: (buff: Buffer) =>
Promise.resolve({
type: 'foobar',
payload: buff,
}),
},
});
这个。是我对foobar函数的错误:
[ts]
Type '(buff: Buffer) => Promise<{ type: string; payload: Buffer; }>' is not assignable to type '(...args: any[]) => Promise<IMessage<{ foobar: (buff: Buffer) => Promise<string>; }, "foobar">>'.
Type 'Promise<{ type: string; payload: Buffer; }>' is not assignable to type 'Promise<IMessage<{ foobar: (buff: Buffer) => Promise<string>; }, "foobar">>'.
Type '{ type: string; payload: Buffer; }' is not assignable to type 'IMessage<{ foobar: (buff: Buffer) => Promise<string>; }, "foobar">'.
Types of property 'type' are incompatible.
Type 'string' is not assignable to type '"foobar"'.
baseUpstreamImpl.ts(11, 5): The expected type comes from property 'foobar' which is declared here on type '{ foobar: (...args: any[]) => Promise<IMessage<{ foobar: (buff: Buffer) => Promise<string>; }, "foobar">>; }'
(property) foobar: (...args: any[]) => Promise<IMessage<{
foobar: (buff: Buffer) => Promise<string>;
}, "foobar">>
这是我的类型:
type EnforcePromise<T, P = any> = T extends Promise<P> ? T : Promise<T>;
type Promised<T> = {
[P in keyof T]: (...args: InferArgs<T[P]>) => EnforcePromise<InferType<T[P]>>
};
type Filter<T, Cond, U extends keyof T = keyof T> = {
[K in U]: T[K] extends Cond ? K : never
}[U];
type EventKey<T> = Filter<T, (...args: any[]) => any>;
interface IMessage<T, K extends EventKey<T> = EventKey<T>> {
type: K;
payload: InferArgs<T[K]>;
}
export interface ProtocolExtension<T, U, R = {}> {
name: string;
type: 'upstream' | 'downstream';
handlers: Promised<T>;
messageCreators: {
[K in keyof U]: (
...args: any[]
) => Promise<IMessage<U>>
};
}
答案 0 :(得分:1)
代码中存在两个问题,都与打字稿推断文字类型的方式有关。
第一个(以及您收到的错误消息)是type: 'foobar'
会推断type
为string
的事实(在没有直接理由将其推断为字符串文字类型'foobar'
)。解决方案是手动将类型断言用于字符串文字类型。
解决此问题后,有效负载出现新错误。 payload
应该是InferArgs<T[K]>
,因此它应该是带有函数参数的元组。您只为其分配一个值。如果我们要写[buf]
,我们将遇到与上面的字符串文字类型问题类似的问题。也就是说,数组文字将被键入为数组而不是元组(同样在没有直接理由将其键入为元组类型的情况下)。
还有第三个问题,即缺少handelrs
属性,但是泰铢可能只是一个疏忽。
const baseUpstreamImpl = (
client: {},
): ProtocolExtension<
{},
{
foobar: (buff: {}) => Promise<string>;
}
> => ({
name: 'base upstream impl',
type: 'upstream',
handlers: null as any,
messageCreators: {
foobar: (buff: {}) =>
Promise.resolve({
type: 'foobar' as 'foobar',
payload: [buff] as [{}],
}),
},
});