The combination of lookup type and variable length argument does not work.

Asked 2 years ago, Updated 2 years ago, 41 views

If I write first, I get an error in the return fn(...args); part of the code below, and I can't get it.What is the cause?

constable={
    add:(a:number, b:number) =>a+b,
    square: (a:number) = > a*a,
} as const;

typeTable = typeof table;
type Key = key of Table;

function calculate <Textends Key> (key:T, ...args:Parameters<Table [T]>): number {
    const fn: Table [T] = table [key];
    return fn (...args);
}

const x = calculate ('add', 1, 2);
consty=calculate('square',3);

What we're trying to do with the code above is first implement a so-called helper function that arranges functions in a table and then uses keys to call one of them.The last two lines are examples of use, and the goal is to force the caller to type the correct argument by making type inference work well according to the key.And since there are no errors in the last two lines, type inference seems to be working in this respect (add and square get an error if the arguments are reversed).

However, in the return fn(...args); part of the calculate function, the fn type should not be determined until T is determined, but if you look at the editor, it appears to be hitting (a:number, b:number)=>number.

To refine the problem, I stopped using the generic to implement calculate and when I wrote only specific literal types as shown below, the error disappeared (so it doesn't seem like a compiler bug to me).

 function calculate (key: 'add', ...args: Parameters <Table ['add'] >): number {
    const fn: Table ['add'] = table [key];
    return fn (...args);
}

Please let me know if you are familiar with type inference or if you know the cause.Thank you for your cooperation.

Supplement:

  • I don't think the error message is essential for this time, but the spread argument must either specify the type of set or pass it to the rest parameter.It was ts(2556)
  • It may seem like a roundabout code, but this code is minimized to detect errors, and the reason why it should look like this is omitted

typescript

2022-09-29 22:09

1 Answers

I solved myself.So the type limit <Textends Key> is never required to be one of the Key.

In the example above, I thought that T would be either 'add' or 'square', but logically, 'add'|'square' can also be fn type cannot be determined at this point.

Suggestions for oneof that require one of the Union types appear to be discussed in this issue.


2022-09-29 22:09

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.