Reputation: 9248
I am getting this error
[ts] Type '{ type: string; }' is not assignable to type 'A'.
with the below code
interface Action {
type: string;
}
function requestEntities<A extends Action>(type: string) {
return function (): A {
return { type };
};
}
Why isn't it assignable? A
extends Action
, which has only one property: type
, which is a string. What's the problem here?
Is the problem that A
could have more properties? then how do I tell TypeScript that A
still only has the type: string
property and nothing else?
EDIT
FYI the reason that I want to add the generic A
is because A
will have a specific string as the type property, e.g. { string: 'FETCH_ITEMS' }
.
Upvotes: 2
Views: 3464
Reputation: 2721
Look what you can do on order to achieve stronger type safety (I didn't fully understand your task, but the approach should be clear from this example)
interface Action {
type: string;
amount: number;
}
const action: Action = { type: 'type1', amount: 123 }
function requestEntities<KEY extends keyof Action>(type: KEY) {
return action[type]
}
requestEntities('type')
requestEntities('amount')
requestEntities('random-stuff')
Upvotes: 0
Reputation: 23712
FYI the reason that I want to add the generic
A
is becauseA
will have a specific string as the type property, e.g.{ string: 'FETCH_ITEMS' }
.
Because you are sure that A
is compatible with Action
, you can reassure the compiler:
return { type } as A;
Upvotes: 2
Reputation: 329418
The generic isn't helping you here. As you note, A
can have more properties:
interface SillyAction extends Action {
sillinessFactor: number;
}
requestEntities<SillyAction>('silliness');
There generally isn't a way in TypeScript to say that an object has only some set of properties, because TypeScript currently lacks exact types.
But in your case, you want the returned Action
to have a type
with a specific string
; something like:
interface SpecificAction<T extends string> extends Action {
type: T;
}
function requestEntities<T extends string>(type: T) {
return function (): SpecificAction<T> {
return { type };
};
}
requestEntities('silliness'); // returns a function returning {type: 'silliness'}
Hope that helps. Good luck!
Upvotes: 5