Reputation: 15379
I'm trying to understand type variables for funcitons. The example uses only one but I'm trying to extend it to two. Various inputs produce outputs I don't understand.
function id<T, U>(arg1, arg2: U): U{ // error 1 below
// return arg2 + arg2; // when uncommented, error 2 below
return arg2 * 2
// ^--^ error 3 below
//^-------------^ error 4 below
}
var result = id<string, number>('lorem', 10)
Error 1
Parameter 'arg1' implicitly has an 'any' type.
Error 2
error Operator '+' cannot be applied to types 'U' and 'U'.
Error 3
The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
Error 4
Type 'number' is not assignable to type 'U'.
I am confused in a couple of areas, so please feel free to suggest if these should be separate questions:
1: Doesn't specifying argument types with <string, number>
register to the called function that these are the types for supplied arguments. Why do these need does : T
need to be given again in the parameter list?
2: U
here should just be a number, why can't I add it?
3: I don't understand what this error is really driving at.
4: This works if I simply return arg2
without the multiplication. I don't understand why I cannot return a number here.
Upvotes: 0
Views: 57
Reputation: 2551
function id<T, U extends SomeClass>(...)
to use SomeClass props inside you func. And you can write "U extends number" to support add/subtract operations. Also you can use valueOf function of your object (used under the hood by js) and cast arg2 to 'any' (no need to use valueOf if your argument is a number already):
// valid TS code:
var obj = {
foo: 123,
valueOf: function(){return this.foo;}
};
console.log((obj as any) + 1); //will be 124
// workaround - using '+' sign (valueOf used as well)
console.log(+obj + 1); //will be 124
Upvotes: 0
Reputation: 138537
The first error tells you, that you should always add a type to a parameter. arg1
is currently untyped.
The other errors tell you:
You can only add up (+
) numbers and strings, not everything (objects for example). Thats why you have to narrow down the generic U to be either a string or a number.
You can only multiply numbers (*
) (and BigInts).
The main point here is: The function has to work without problems in every possible case.
Upvotes: 1
Reputation: 2022
1: Doesn't specifying argument types with register to the called function that these are the types for supplied arguments. Why do these need does : T need to be given again in the parameter list?
The types in the function declaration don't map 1:1 with its parameters. If you want arg1
to be of type U
, you'll need to specify it.
2: U here should just be a number, why can't I add it?
3: I don't understand what this error is really driving at.
4: This works if I simply return arg2 without the multiplication. I don't understand why I cannot return a number here.
Just need to tell TypeScript that U
is a number: <T, U extends number>
.
Also to note, the compiler can figure out the return type of your function in this case, so you can omit it. I think you want to end up somewhere like this:
function id<T, U extends number>(arg1: T, arg2: U) {
return arg2 * 2;
}
Upvotes: 0