Reputation: 5845
Let's say I have a generic type Gen<T>
:
type Gen<T> = {
t: T,
x: boolean,
};
And then I have some function that takes in a Gen
but does not care about the T
type:
function handleGen1(gen) {
if (gen.x) {
return gen;
}
}
How would I type handleGen1
? Currently I can only see this way:
function handleGen1<T>(gen: Gen<T>) {
if (gen.x) {
return gen;
}
}
Is there a cleaner way, like in Flow (function handleGen1(gen: Gen<*>) { ... }
)?
Also, what if my function depends only on some of the type arguments?
type Gen<P, E> = {
p: P,
e: E,
x: boolean,
}
function handleGen2(gen) {
if (gen.x) {
return gen.p;
}
}
I would like to type that as:
handleGen2: (gen: Gen<P, *>) => P;
Upvotes: 2
Views: 1455
Reputation: 250336
There is no equivalent to the *
syntax in typescript. The option you found with declaring the type parameter is a good one. Note that at call site the extra parameter does not have to be specified, typescript will infer the apropriate T
type Gen<T> = {
t: T,
x: boolean,
};
function handleGen1<T>(gen: Gen<T>) {
if (gen.x) {
return gen;
}
}
handleGen1({
t: 1,
x: true
}) // T infered as number
If you have more parameters to Gen
you will to declare one for each type parameter:
type Gen<T, P> = {
t: T,
p: P,
x: boolean,
};
function handleGen1<T, P>(gen: Gen<T, P>) {
if (gen.x) {
return gen;
}
}
handleGen1({
t: 1,
p: "",
x: true
}) // T inferred as number, P number
Now if you truly don't use the type parameter in any other position you can go with Gen<any>
or Gen<unknown>
. In your example, you do use T
since the return type is going to be Gen<T>
so Gen<any>
will not forward the type parameter. If that were not the case we can use this option:
type Gen<T> = {
t: T,
x: boolean,
};
function handleGen1(gen: Gen<unknown>) {
if (gen.x) {
console.log(gen.t);
}
}
handleGen1({
t: 1,
x: true
}) // works fine 1 is assignable to unknown
A disadvantage of having to specify the type parameters is having to specify the type constraint as well.
Upvotes: 3