TypeScript - 将动态属性名称传递给子级

2024-01-23

我正在开发一个带有嵌套路由的路由库,我试图定义一个推断父路径的子处理函数。原因是我有另一种类型,可以从字符串推断动态路径参数(例如,users/:id to { id: string });因此,我希望能够将推断的路径参数从父路由传递到每个子路由处理函数中的任何和所有子路由。

这是我到目前为止所拥有的:

type RawRouterDefn<Namespace extends string = ""> = {
    [K: string]: Handler<Namespace, typeof K> | RawRouterDefn<`${Namespace}/${typeof K}`>;
};

type Handler<DataPath extends string, Path extends string> = ((args: { dataPath: DataPath, path: Path }) => unknown)

type Router<Routes extends RawRouterDefn, DataPath extends string = ""> = {
    [K in keyof Routes & string]: Routes[K] extends CallableFunction
        ? Handler<DataPath, K>
        : Router<Routes[K], `${DataPath}/${K}`>;
};

function createRouter<T extends RawRouterDefn>(rawDefn: T): Router<T, ""> {
    // Implementation not important right now
    return {} as unknown as Router<T, "">
}

const router = createRouter({
    some: {
        deeply: {
            nested: {
                /**
                 * Here, dataPath should be inferred as `some/deeply/nested`,
                 * path should be `route`
                 */
                route: ({ dataPath, path }) => {}
            },
        },
    },
});

const route = router.some.deeply.nested.route;
// Correctly inferred **after** function applied, I need it within the router definition
type Params = Parameters<typeof route>[0]

(以及link https://www.typescriptlang.org/play?#code/C4TwDgpgBASghgdxgewK7AgJwCIQGYB2APAHJwC2EAzmHAMbQQAeGBAJlVFcJgJYEBzKAF4oAIjEA%20EVADeAKACQAbQDSALi49%20AgLqaAEnHYAbLKQrVaDADRRQkZHiirpAH1iIU6LLkJEAAwASWTJKGnoIAF8AehCHCCcXKIDJAG55KIz5BKgjU3NsOGA4AAVigAsoZlYOLT5BO3LgKpqIdk5uBoFpUQAKPrhMASpNWSg2YrLKzSKS5oq7WhbNBagogEoRaVQCAGsCZAQCDfkc8GhvDEwiK%20pqlna6%20CQ0a78COznplofazu0ghkEl6ciUaig-CgewgICSd04ADJ6jp9LA3tQ1Lo-k9OABhOAmExwABGZgAYrs6MBeMgCEpFAB%20PLGNhmG7fBZ2VwMzR3G4IrF2YKyTmVWIhVQpdKZbJ4Kk0ulQOiYCDFCD8ogAFRxHU8rx8OHwBEkfUwiA%20mi1Gz5GJuWrsILBUCgMRiUAAkuQwGZKAQSoqCFBDsBId7kJgSv6oHwBBVQ4dUFQIPIXargKhMEHZFEoHBOLsDkcg-n0YbtY6pJkznQ6dwY3aZCq1Rh%20X0FIoqMhKGMGWwIBAfSBe4pRwRqBg2L2XTOZzEAFTz1Oz2fzvJYCB2SbzSpcCpoExsKAk6D8PBYVVH0sBLuUGL9wcmEAxcfcCBsAI2Zcrl1r5ZVKh91QQ9j2gAJMAxAJvx-ecYgZUcIJ8TR2wmKYuSgf91i2YRpBzeCoi-UcCKUYjNmyWsCHrRCMBkaisAAOlvCB6IfId6NfSd6LojI3SgPEI1Vakn0hAhz0wS8oEXOA8GuRcoHlAhqVpEswB9Xh3zsD1gwHI9eFDBA9IqKEWmgOjMAmfB%20D05TzkgKBynNchOFEBzLGuKgiASJI6MkZQAAZdCAA去游乐场)

我就快到了,除了dataPath应该推断为/some/deeply/nested并不是/${string}/${string}/${string} and path应该推断为/route并不是/${string}。这对我来说表明我缺少一些东西RawRouterDefn type.

所以看来我可以正确地缩小字符串的形状,但用我目前的方法无法进一步缩小。

同样,我需要在用作函数参数时(而不是之后)推断它。


非常接近,只需要对泛型做一点魔法:

function createRouter<T extends RawRouterDefn, R extends Router<T, "">>(rawDefn: R): R {

现在它可以工作了:https://tsplay.dev/NDRE1W https://tsplay.dev/NDRE1W

您需要另一个泛型来告诉 TypeScript 您在函数中得到的正是您返回的。去除T extends RawRouterDefn并使用R extends Router<RawRouterDefn, "">打破了推论,所以呃,不要这样做。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TypeScript - 将动态属性名称传递给子级 的相关文章

  • 不寻常的通用语法:Arrays.asList(...)

    我发现了一个 不寻常 的通用语法 例如 Arrays
  • 如何将值发布到输入框中?

    Intro I would like to get the current time after clicking at click and POST the value into input text box Note 假设包含引导样式表
  • JavaScript 字符串中的脚本标签[重复]

    这个问题在这里已经有答案了 我遇到一个问题 即 JavaScript 中带引号的字符串内有结束脚本标记 并且它正在杀死脚本 我认为这不是预期的行为 可以在这里看到这样的示例 http jsbin com oqepe edit http js
  • 使用函数重载进行解构

    我正在尝试创建一个函数 该函数需要一对坐标或一个对象x and y属性并返回邻居列表 但由于某种原因 即使我检查了它的类型 我也无法解构该对象 interface Coords x number y number public getNei
  • 将时间戳转换为一个数组

    在应用程序脚本 谷歌表中运行 我从 API 获取时间戳并返回此结果 1 6370611672429312E18 1 63706107263277082E18 我执行此代码并且工作正常 但问题不在数组中 我每次都需要它在数组中 const t
  • 我可以在 GWT 中使用第三方 Javascript 库吗

    例如穆工具 用 js 编码对我来说很舒服 但显然不适合所有人 你当然可以 最好的事情就是给自己写一些好看的JavaScript 覆盖类型 http code google com webtoolkit doc latest DevGuide
  • 使用javascript以编程方式触发iOS safari中的复制菜单?

    我正在尝试实现一种用户友好的方式 将一些文本从文本输入字段复制到 iOS Safari 上的剪贴板 我知道无法在这个平台上以编程方式完成此操作 但我希望能够尽可能地指导用户体验 在 iOS Safari 上 当用户手动突出显示某些文本时 会
  • 通过 JavaScript 单击按钮/页面提交

    我想了解 asp net 框架如何知道何时单击了按钮 因此一旦收到请求 就会在服务器上触发其单击事件 我需要了解它是如何工作的 因为我想从 JavaScript 触发按钮的服务器单击事件 我能够从 JavaScript 执行页面提交 doc
  • 可以禁用幻灯片的触摸模拟但不能禁用滚动条(危险的滑动器)吗?

    我的页面上有一个危险的滑动器 它成功地模拟了幻灯片和随附滚动条上的触摸事件 允许单击鼠标并移动以向左或向右滑动幻灯片 这很好 但我现在在滑动器内的幻灯片上调用了可拖动 这意味着我需要停止此触摸模拟 拖动幻灯片并同时移动它们会引起混乱 但仅限
  • 从链接打开本地文件夹

    如何通过单击任何链接打开本地文件夹视图 我尝试了很多选择 例如 a href Open folder a or a Open folder a or a Open folder a 解决方案 启动可下载链接 以下内容适用于所有浏览器 但一如
  • 如何让 Typescript 获取声明文件?

    My file src auth ManagementAPI ts使用 Auth0 我需要使用自己的声明文件并创建src types auth0 d ts 然而 当我跑步时ts node 我收到此错误 TSError Unable to c
  • 如何导入 nano (couchdb) - typescript

    我在节点应用程序中导入和使用 nano 时遇到问题 js 方式 来自文档 是 var nano require nano http localhost 5984 我该如何用打字稿做到这一点 I tried import as Nano fr
  • 在打字稿中获取类的键

    我有一个包含很多方法的类 我们称之为 myClass 我这样称呼它 myClass key 有没有办法从 key 获取可能的值 我希望有类似 keyof myClass 的东西 但我得到 myClass 引用一个值 但在这里被用作类型 问题
  • 为什么 call 比 apply 快那么多?

    我想知道是否有人知道why call比apply 在 Chrome 中 速度大约快 4 倍 在 Firefox 中快 30 倍 我什至可以制作自定义原型 apply2 在大多数情况下 运行速度是apply 这个想法取自角度 Function
  • 在反应中访问回调内的 event.target

    我有以下课程片段 constructor props super props this timeout null search e gt clearTimeout this timeout this timeout setTimeout f
  • javascript - 如何获取对象名称或关联数组索引名称?

    我有一个像这样的 JSON 对象 var list name1 element1 value1 name2 element1 value2 如何提取所有 nameX 字符串值 例如 假设我想将它们连接在一个字符串中输出 例如 name1 n
  • onPress 方法中箭头函数与普通函数的行为

    正在学习 Native React 并学习更多关于 javascript 的知识 所以我仍然不明白它的行为的很多事情 我使用 TouchableOpacity 及其 onPress 属性创建了一个按钮组件 为了让它工作 我必须发送我想要执行
  • 如何在 TypeScript 中使用 navigation.replace ?

    我试图在我的代码中使用它 const navigation useNavigation navigation replace AllFriends 但我不断收到错误消息 Property replace does not exist on
  • Graphql 将多个查询合并(组合)为一个?

    我正在尝试使用 JavaScript 将多个 GraphQL 查询合并为一个查询 我正在寻找这样的东西 let query3 mergeQueries query1 query2 我们事先不知道哪些查询将被组合 假设我有这样的查询 输入查询
  • Angular 4 中的箭头函数(Lambda 函数)

    我对lambda知之甚少 lambda表达式被视为一个函数 我们有很多方法可以做到这一点 这是我的简单功能TypeScript file byPan card1 card2 return card1 pan card2 pan 我在 HTM

随机推荐