Reputation: 294
Consider the following code (TS Playground):
function identity<T>(value: T): T {
if (typeof value === 'string') {
return value.replace('foo', 'bar'); // <-- ERROR
}
return value;
}
It results in the error Type 'string' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'string'.
It seems that the type guard is not sufficient to narrow the type of the generic parameter and perform a string operation.
Why does this error occur and how would I resolve it?
Upvotes: 0
Views: 440
Reputation: 84912
Suppose the function gets called like this
const example: 'foo' = 'foo';
const result = identity(example);
According to the type definition of the function, since T
is "foo"
(ie, a specific string, not a general string
), i must be returned a "foo"
as well. But the code inside the function will return "bar" instead, so it's violating the types.
To do what you want, you'll want to use function overloading to give it different types for the string case than for other cases. For example:
function identity<T>(value: string): string;
function identity<T>(value: T): T;
function identity<T>(value: T): T | string {
if (typeof value === 'string') {
return value.replace('foo', 'bar');
}
return value;
}
If this code is called with T
== "foo"
, then typescript will see that a value of "foo"
is compatible with value: string
, so the first type definition for the function matches. According to that type definition, the return value is thus a general string
.
Upvotes: 1