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

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

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

  1. type KeysToValues<O extends Record<string, any>, K> = K extends [
  2. infer G,
  3. ...infer L
  4. ]
  5. ? G extends keyof O
  6. ? [O[G], ...KeysToValues<O, L>]
  7. : []
  8. : []
  9. function useWatchProps<
  10. O extends Record<string, any>,
  11. K extends keyof O = keyof O,
  12. T extends K | K[] = K | K[]
  13. >(
  14. keys: T,
  15. callback: (values: T extends K ? O[K] : KeysToValues<O, K>) => void
  16. ) {}
  17. useWatchProps<{ a: number; b: string }>('a', (a) => {
  18. a // number
  19. })
  20. useWatchProps<{ a: number; b: string }>(['a', 'b'], ([a, b]) => {
  21. a // number
  22. b // string
  23. })

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:

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

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:

  1. type KeysToValues<O extends Record<string, any>, K> = K extends readonly [
  2. infer G,
  3. ...infer L,
  4. ]
  5. ? G extends keyof O
  6. ? [O[G], ...KeysToValues<O, L>]
  7. : []
  8. : K

Implementation:

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

Usage:

  1. useWatchProps<{ a: number; b: string }>()('a', (a) => {
  2. a; // number
  3. });
  4. useWatchProps<{ a: number; b: string }>()(['a', 'b'], ([a, b]) => {
  5. a; // number
  6. b; // string
  7. });

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:

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

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:

  1. type KeysToValues&lt;O extends Record&lt;string, any&gt;, K&gt; = K extends readonly [
  2. infer G,
  3. ...infer L,
  4. ]
  5. ? G extends keyof O
  6. ? [O[G], ...KeysToValues&lt;O, L&gt;]
  7. : []
  8. : K

Implementation:

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

Usage:

  1. useWatchProps&lt;{ a: number; b: string }&gt;()(&#39;a&#39;, (a) =&gt; {
  2. a; // number
  3. });
  4. useWatchProps&lt;{ a: number; b: string }&gt;()([&#39;a&#39;, &#39;b&#39;] , ([a,b]) =&gt; {
  5. a; // number
  6. b; // string
  7. });

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:

确定