typescript 告诉函数的返回类型使用参数值的类型

2ledvvac  于 2023-02-10  发布在  TypeScript
关注(0)|答案(1)|浏览(127)

有没有一种方法可以推断通过函数传递的属性的类型,而不用将其作为泛型传递给被调用方?

interface Externals<T> {
  validator: (schema: T) => void;
}

export async function createAction(schemaValue: z.AnyZodObject): Promise<(externals: Externals<SchemaType>) => Promise<void>> {
  type SchemaType = z.infer<typeof schemaValue>;
  return async (externals: Externals<SchemaType>): Promise<void> => {
    externals.validator(schemaValue);
  };
}

然后使用上述方法:

// whilst I'm using zod here, this could be any dynamic object
const schemaValue = z.object({
  translatedValue: z.string().or(z.number())
});
async function runAction(): Promise<void> {
  const action = await createAction(schemaValue);
  await action({
    async validator(schema) {
      // schema is of type SchemaType, but there's no intellisense as the
      // return type isn't correct on createAction
    }
  });
}

这不起作用,因为createAction的returnType不正确,我知道我可以更改

export async function createAction<T>(schemaValue: z.AnyZodObject): Promise<(externals: Externals<T>) => Promise<void>> {
  return async (externals: Externals<T>): Promise<void> => {
    externals.validator(schemaValue as T);
  };
}
async function runAction(): Promise<void> {
  const action = await createAction<z.infer<typeof schemaValue>>(schemaValue);
  await action({
    async validator(schema) {
      // this works, schema is the correct type
    }
  });
}

上面的工作,但它是一个非常简单的表示我所实现的,有很多“模式”要传递和高度动态,我想知道是否有一个更好的方式来实现这一点,而不通过z. infers作为泛型类型的createAction方法?

xytpbqjk

xytpbqjk1#

这可以通过z.Schema<T>实现。
当使用schemaValue: z.AnyZodObject时,泛型是未知的,因为泛型仅在参数中自动推断。
完整示例:

interface Externals<T> {
  validator: (schema: T) => void;
}
const schemaValue = z.object({
  translatedValue: z.string().or(z.number())
});
export async function createAction<T>(schemaValue: z.Schema<T>/*see here*/): Promise<(externals: Externals<T>) => Promise<void>> {
  return async (externals: Externals<T>): Promise<void> => {
    externals.validator(schemaValue as T);
  };
}
async function runAction(): Promise<void> {
  const action = await createAction(schemaValue); // see here
  await action({
    async validator(schema) {
      // this works, schema is the correct type
      // no infer
    }
  });
}

相关问题