如何根据函数参数约束类型的 TypeScript 方法?

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

Typescript, How to constrain types according to function parameters?

问题

如何限制T以符合键的要求。

英文:

What can be done to make the useWatchProps callback function parameters correspond to the first parameter

type KeysToValues<O extends Record<string, any>, K> = K extends [
  infer G,
  ...infer L
]
  ? G extends keyof O
    ? [O[G], ...KeysToValues<O, L>]
    : []
  : []

function useWatchProps<
  O extends Record<string, any>,
  K extends keyof O = keyof O,
  T extends K | K[] = K | K[]
>(
  keys: T,
  callback: (values: T extends K ? O[K] : KeysToValues<O, K>) => void
) {}

useWatchProps<{ a: number; b: string }>('a', (a) => {
  a // number
})
useWatchProps<{ a: number; b: string }>(['a', 'b'], ([a, b]) => {
  a // number
  b // string
})

How to constrain T by keys

答案1

得分: 0

以下是您要的翻译内容:

"Since you are not passing the T, it gets automatically turned to the default value that you have assigned. Unfortunately, we can't specify only the portion of the required parameters; thus, I can suggest making useWatchProps accept only O and return another function. Usage will look like this:

useWatchProps<{ a: number; b: string }>()('a', (a) => {
  a; // number
});

We will also need to change T to a const type parameter to avoid compiler turning the T to a union. This will cause to turn all checks of the T to readonly some_array/some_tuple.

Modifications:

type KeysToValues<O extends Record<string, any>, K> = K extends readonly [
  infer G,
  ...infer L,
]
  ? G extends keyof O
    ? [O[G], ...KeysToValues<O, L>]
    : []
  : K

Implementation:

function useWatchProps<O extends Record<string, any>>() {
  return <const T extends keyof O | readonly (keyof O)[]>(
    keys: T,
    callback: (values: T extends keyof O ? O[T] : KeysToValues<O, T>) => void,
  ) => {};
}

Usage:

useWatchProps<{ a: number; b: string }>()('a', (a) => {
  a; // number
});
useWatchProps<{ a: number; b: string }>()(['a', 'b'], ([a, b]) => {
  a; // number
  b; // string
});

playground"

希望这对您有所帮助。

英文:

Since you are not passing the T, it gets automatically turned to the default value that you have assigned. Unfortunately, we can't specify only the portion of the required parameters; thus, I can suggest making useWatchProps accept only O and return another function. Usage will look like this:

useWatchProps&lt;{ a: number; b: string }&gt;()(&#39;a&#39;, (a) =&gt; {
  a; // number
});

We will also need to change T to a const type parameter to avoid compiler turning the T to a union. This will cause to turn all checks of the T to readonly some_array/some_tuple.

Modifications:

type KeysToValues&lt;O extends Record&lt;string, any&gt;, K&gt; = K extends readonly [
  infer G,
  ...infer L,
]
  ? G extends keyof O
    ? [O[G], ...KeysToValues&lt;O, L&gt;]
    : []
  : K

Implementation:

function useWatchProps&lt;O extends Record&lt;string, any&gt;&gt;() {
  return &lt;const T extends keyof O | readonly (keyof O)[]&gt;(
    keys: T,
    callback: (values: T extends keyof O ? O[T] : KeysToValues&lt;O, T&gt; ) =&gt; void,
  ) =&gt; {};
}

Usage:

useWatchProps&lt;{ a: number; b: string }&gt;()(&#39;a&#39;, (a) =&gt; {
  a; // number
});
useWatchProps&lt;{ a: number; b: string }&gt;()([&#39;a&#39;, &#39;b&#39;] , ([a,b]) =&gt; {
  a; // number
  b; // string
});

playground

huangapple
  • 本文由 发表于 2023年5月22日 17:31:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76304776.html
匿名

发表评论

匿名网友

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

确定