question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Type annotation for named parameters

See original GitHub issue

I’m now building my first Cloudflare Workers app, and the experience with Hono has been great so far!

During the development, I wish I could annotate types for named parameters. For example, if a named parameter is in the form of :param@number, c.req.param("param") evaluates to a value of type number. If no type is annotated (i.e., :param), its type should fall back to string. This is inspired by a similar feature of aspida.

With this syntax, users don’t need to validate or convert number parameter on their own, so the code becomes simpler and less. Would it be possible to add this feature?

Below is a type-level PoC of my proposal (TS Playground link). I’m not familiar with the internal of Hono yet, so not sure about how easy/difficult it is to integrate this into your codebase.

type ExampleRoute = "/api/:author/:title@string/:price@number/:param@invalid";
declare const getterImpl: <
  Route extends string,
  Param extends EnumParams<Route>
>(
  param: Param
) => InferParamTypeFromRoute<Route, Param>;
const getter = <Param extends EnumParams<ExampleRoute>>(param: Param) =>
  getterImpl<ExampleRoute, Param>(param);

const author = getter("author"); // string
const title = getter("title"); // string
const price = getter("price"); // number
const param = getter("param"); // never
// @ts-expect-error
const nonExistent = getter("non-existent");

type InferParamTypeFromRoute<
  Route extends string,
  Param extends EnumParams<Route>
> = GetTypeFromObjectUnion<EnumParamTypes<SplitRoute<Route>>, Param>;

// EnumParams<"/:foo/:bar@number"> --> "foo" | "bar"
type EnumParams<Route extends string> = EnumParamTypes<
  SplitRoute<Route>
> extends infer T
  ? T extends T
    ? keyof T
    : never
  : never;

// GetTypeFromObjectUnion<{ foo: string } | { bar: number }, "bar"> --> number
type GetTypeFromObjectUnion<T, K extends string> = T extends T
  ? K extends keyof T
    ? T[K]
    : never
  : never;

// EnumParamTypes<[":foo", ":bar@number"]> --> { foo: string } | { bar: number }
type EnumParamTypes<Params extends string[]> = {
  [I in keyof Params]: Params[I] extends `:${infer Name}@${infer Type}`
    ? Record<Name, TypeNameToPrimitive<Type>>
    : Params[I] extends `:${infer Name}`
    ? Record<Name, string>
    : never;
}[number];

type TypeNameToPrimitive<T extends string> = T extends "string"
  ? string
  : T extends "number"
  ? number
  : never;

type SplitRoute<R extends string> = R extends `/${infer Head}/${infer Rest}`
  ? [Head, ...SplitRoute<`/${Rest}`>]
  : R extends `/${infer Root}`
  ? [Root]
  : [];

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:10 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
yudai-nktcommented, May 17, 2022

Okay, I’ll take on that. I suppose I can have some time this weekend.

0reactions
yusukebecommented, May 18, 2022

@yudai-nkt @usualoma It was an interesting discussion, Thank you!

Read more comments on GitHub >

github_iconTop Results From Across the Web

typing — Support for type hints — Python 3.11.1 documentation
Source code: Lib/typing.py This module provides runtime support for type hints. The most fundamental support consists of the types Any, Union, Callable, ...
Read more >
Type annotations for named parameters #1075 - GitHub
Named parameters via object destructuring are already relatively popular. For example: function f({x, y, s}) {} How would one add type ...
Read more >
Understanding type annotation in Python - LogRocket Blog
In this extensive post with specific examples, learn how to use Python type annotation to your advantage using the mypy library.
Read more >
Type annotations for *args and **kwargs - Stack Overflow
While you can annotate variadic arguments with a type, I don't find it very useful because it assumes that all arguments are of...
Read more >
Using type annotations | Learn TypeScript
The syntax for a type annotation on a parameter is just like type annotations on variables - a colon followed by the type...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found