I wrote three functions with same type for each of them, let's see them.
const func: <T extends string, K extends number = any>(arg: T) => K = () => {
return 1;
};
const anotherFunc = <T extends string, K extends number = any>(arg: T): K => {
return 1;
};
function someFunc<T extends string, K extends number = any>(arg: T): K {
return 1;
}
as you can see i defined K
as number in all of them to returns a number in each of them, but a weird error occured that says:
this is for the first function:
Type '() => 1' is not assignable to type '<T extends string, K extends number = any>(arg: T) => K'.
Type 'number' is not assignable to type 'K'.
'number' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'number'.
and this is for the last two functions:
Type 'number' is not assignable to type 'K'.
'number' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'number'
i think the two errors have same point. why typescript can't realize that type?
thanks for any help.
CodePudding user response:
I'm not sure whether this is a duplicate or not, but please take a look at this answer
Here is the simplified version of first example:
const func: <K extends number>() => K = () => {
return 1;
};
Now, try to call this function:const result = func<42>(); // 42
. TS assumes, return type/value is 42
, but it is 1
in runtime.
Further more, 42 & { WAAAT: () => '?????' }
is a valid subtype of number.
const result = func<42 & { WAAAT: () => '?????' }>();
result.WAAAT() // ?????
Above code compiles in TypeScript but throws a runtime error in runtime. Please see the error message:
K
could be instantiated with a different subtype of constraintnumber
42 & { WAAAT: () => '?????' }
is a valid subtype of constraint number
.
Hence, don't treat extends
as equal
operator.
Please see my article for more examples
CodePudding user response:
Couple of observations.
- why do u have
args:T
if you never use it? - why are you extending a primitive
string and number
and assigning an any type toK
? - your first
function
is wrong. Lets transformer to a classic function
const func: <T extends string, K extends number = any> function (args:T) {
return K = function () {
return 1;
}
}
Did you see the two errors ?
- to assign value we use
=
which you are not using in func look at anotherFunc for example - you forgot to add the third error which Is
Declaration or statement expected.