在Typescript中,使用常量创建接口中的函数。

huangapple go评论99阅读模式
英文:

Create function in interface with name from const in Typescript

问题

  1. export const Events = {
  2. user_updated: "user:updated",
  3. empty: "empty"
  4. }
  5. interface ServerToClientEvents {
  6. [Events.empty]: () => void;
  7. [Events.user_updated]: (user: User) => void;
  8. }
英文:

Is it possible to create function in interface with name from const? I have const where I have all event names and I want to create ServerToClientEvents interface for SocketIO.

I can write something like this and it will work

  1. interface A {
  2. "funcName": () => void
  3. }

But can I create functions in this interface with names from FunNames?

  1. export const Events = {
  2. user_updated: "user:updated",
  3. empty: "empty"
  4. }
  5. interface ServerToClientEvents {
  6. Events.empty: () => void;
  7. Events.user_updated: (user: User) => void;
  8. }

答案1

得分: 2

如果Events不是动态的,也许const断言可以胜任任务。

  1. export const Events = {
  2. user_updated: 'user:updated',
  3. empty: 'empty',
  4. } as const; //const断言
  5. interface User {
  6. id: string;
  7. }
  8. interface ServerToClientEvents {
  9. [Events.empty]: () => void;
  10. [Events.user_updated]: (user: User) => void;
  11. }
英文:

If Events isn't dynamic, maybe const assertion can do the job.

  1. export const Events = {
  2. user_updated: 'user:updated',
  3. empty: 'empty',
  4. } as const; //const assertion
  5. interface User {
  6. id: string;
  7. }
  8. interface ServerToClientEvents {
  9. [Events.empty]: () => void;
  10. [Events.user_updated]: (user: User) => void;
  11. }

答案2

得分: 1

你可以使用一个mapped type和一个嵌套的conditional type,测试我们映射的键是否与template literal type匹配(这样我们可以检测是否需要user参数):

  1. export const Events = {
  2. user_updated: "user:updated",
  3. empty: "empty",
  4. };
  5. type ServerToClientEvents = {
  6. [Key in keyof typeof Events]: Key extends `user_${string}` ? (user: User) => void : () => void;
  7. };
  8. const goodExample: ServerToClientEvents = {
  9. user_updated(user: User) {},
  10. empty() {},
  11. };
  12. const badExample: ServerToClientEvents = {
  13. //^^^^^^^^^^^−−−−− Property 'empty' is missing in type '{ user_updated(user: User): void; }' but required in type 'ServerToClientEvents'.ts(2741)
  14. user_updated(user: User) {},
  15. };

Playground链接

在那里,我假设user_前缀应该表示函数接受一个User对象,根据问题中显示的代码,但你当然可以根据需要进行调整。

使用给定的Events常量,该映射类型定义了这个结构:

  1. {
  2. user_updated: (user: User) => void;
  3. empty: () => void;
  4. }

在Typescript中,使用常量创建接口中的函数。

为了提高可读性,你可以拆分条件类型:

  1. type ServerFunctionType<Key extends string> =
  2. Key extends `user_${string}`
  3. ? (user: User) => void
  4. : () => void;
  5. type ServerToClientEvents = {
  6. [Key in keyof typeof Events]: ServerFunctionType<Key>;
  7. };

Playground链接

英文:

You can do it with a mapped type and a nested conditional type testing the key we're mapping to see if it matches a template literal type (so we detect whether we need the user parameter):

  1. export const Events = {
  2. user_updated: &quot;user:updated&quot;,
  3. empty: &quot;empty&quot;,
  4. };
  5. type ServerToClientEvents = {
  6. [Key in keyof typeof Events]: Key extends `user_${string}` ? (user: User) =&gt; void : () =&gt; void;
  7. };
  8. const goodExample: ServerToClientEvents = {
  9. user_updated(user: User) {},
  10. empty() {},
  11. };
  12. const badExample: ServerToClientEvents = {
  13. //^^^^^^^^^^^−−−−− Property &#39;empty&#39; is missing in type &#39;{ user_updated(user: User): void; }&#39; but required in type &#39;ServerToClientEvents&#39;.ts(2741)
  14. user_updated(user: User) {},
  15. };

Playground link

I've assumed there that the user_ prefix should mean the function accepts a User object, given the code shown in the question, but of course you can tweak that as necessary.

With the given Events constant, that mapped typ defines this structure:

  1. {
  2. user_updated: (user: User) =&gt; void;
  3. empty: () =&gt; void;
  4. }

在Typescript中,使用常量创建接口中的函数。

For readability, you might split out the conditional type:

  1. type ServerFunctionType&lt;Key extends string&gt; =
  2. Key extends `user_${string}`
  3. ? (user: User) =&gt; void
  4. : () =&gt; void;
  5. type ServerToClientEvents = {
  6. [Key in keyof typeof Events]: ServerFunctionType&lt;Key&gt;;
  7. };

Playground link

huangapple
  • 本文由 发表于 2023年3月9日 19:02:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75683702.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定