Frequently asked TypeScript question
I think my code is correct! Why it is complaining type error to me?
How can I do something in TypeScript?
Case 1: Add function
function add<T extends number | bigint>(left: T, right: T): T {
return left + right
}
TS2365: Operator '+' cannot be applied to types 'T' and 'T'.
Explain: Consider this code:
add<number | bigint>(1, 2n)
This call is valid but it will cause a runtime error therefore TypeScript is correct to give the error in the implementation of add
.
Because in TypeScript you cannot require the generics T is a "concrete" type that only can be "number" or "bigint" but not "number | bigint", therefore this error is not a false-positive.
One of the correct way to implement an add
function is:
const add: {
(x: number, y: number): number
(x: bigint, y: bigint): bigint
} = ((a: any, b: any) => a + b) as any
add(1, 2) // ok
add(1n, 2n) // ok
add(1, 2n) // error
Case 2: Incompatible index signatures
How to write a type that have index signatures with incompatible named properties?
interface T {
// @ts-ignore
name: string
[index: string]: number
}
Explain:
When looking up properties on a type, TypeScript first find if there is matching named properties, in this case, name
. If there is not, the compiler will try to lookup if there is index signature.
Without @ts-ignore
the compiler will report "string" is not assignable to "number" but that error doesn't make type T
becomes any. By ignoring the error, we create a type that have incompatible signatures.
To create an instance of this type, you will need to use as any
because when assigning, the compiler first check if name
is matching string
(the named signature), then also check if it is matching the index signature (number
in the case) which is not possible.