首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让TS推断通用构建器函数中的回调?

如何让TS推断通用构建器函数中的回调?
EN

Stack Overflow用户
提问于 2021-08-02 17:50:51
回答 2查看 186关注 0票数 15

考虑以下用例演示(playground):

代码语言:javascript
复制
// A builder that can self-reference its keys using a ref function
declare function makeObj<K extends string>(
    builder: (ref: (k: K) => number) => Record<K, number>
): Record<K, number>;

// Not using `ref` for now. All good, K is inferred as <"x" | "y">.
const obj1 = makeObj(() => ({ x: 1, y: 2 }));

// Oops, now that we try to use `ref`, K is inferred as <string>.
const obj2 = makeObj(ref => ({ x: 1, y: ref("invalid key, only x or y") }));

// This works, but we'd want K to be automatically inferred.
const obj3 = makeObj<"x" | "y">(ref => ({ x: 1, y: ref("x") }));

那么,我应该如何编写makeObj来自动推断K呢?

EN

回答 2

Stack Overflow用户

发布于 2021-08-09 08:19:15

尝试将Record<K, number>声明为第二个泛型类型。

playground

代码语言:javascript
复制
declare function makeObj<K extends string, T extends Record<K, number> = Record<K, number>>(
  builder: (ref: (k: K) => number) => T
): T

const obj1 = makeObj(() => ({ x: 1, y: 2 }));
const obj2 = makeObj(ref => ({ x: 1, y: ref("invalid key, only x or y") }));
const obj3 = makeObj(ref => ({ x: 1, y: ref("x") }));

限制

嗯,正如@kaya3在下面评论的那样。此解析只能推断返回类型。除非显式设置泛型类型,否则它仍然找不到无效的键。

代码语言:javascript
复制
// error will shown when given explicit generic type
const obj2 = makeObj<'x' | 'y'>(ref => ({x: 1, y: ref("invalid key, only x or y")}));
票数 1
EN

Stack Overflow用户

发布于 2021-08-13 18:43:11

代码语言:javascript
复制
type Ref<Obj> = {
  ref<Key extends string & keyof Obj>
      (k:`${Key}`):Obj[Key]
};

declare function makeObject<Type>(obj: Type): Type & Ref<Type>;


const person = makeObject({
  firstName: "Saoirse",
  lastName: "Ronan",
  age: 26
});

person.ref('firstName') // (method) ref<"firstName">(k: "firstName"): string

// Argument of type '"firstNme"' is not assignable to 
// parameter of type '"firstName" | "lastName" | "age"'.ts(2345)
person.ref('firstNme') // ERROR

person.ref('age') // (method) ref<"age">(k: "age"): number

参考"String Unions in Types"

不幸的是,当您在makeObject调用中声明对象时,您不能访问ref。幸运的是,原生Javascript的近似性已经相当不错了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68625995

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档