-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Allow type assertions from T
-constrained type variable to subtypes of T
#20821
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Could you elaborate on why using |
I have an other class Store class Store {
db = new Map<ActionType, Action[]>();
service = new Service();
store(action: Action) {
if (this.db.has(action.type)) {
this.db.set(action.type, []);
}
this.db.get(action.type).push(action);
this.service.exec(action);
}
storeGeneric<T extends Action>(action: T) {
if (this.db.has(action.type)) {
this.db.set(action.type, []);
}
this.db.get(action.type).push(action);
this.service.exec(action);
}
} const store = new Store(); This example doesn't work store.store({
type: ActionType.Call,
context: {}
}); Argument of type '{ type: ActionType; context: {}; }' is not assignable to parameter of type 'Action'.
Object literal may only specify known properties, and 'context' does not exist in type 'Action'. This example works store.storeGeneric<CallAction>({
type: ActionType.Call,
context: {}
}); That's why I use T instead Action in my Service. I see there is no problem when I switch to a non Generic method. But I want to know why it doesn't work, it's a non intuitive behavior... |
I solved the problem using generic class instead of generic methods interface Typed<U> {
type: U;
}
interface Service<T extends Typed<U>, U> {
exec(action: T): T;
}
class Store<T extends Typed<U>, U> {
db = new Map<U, T[]>();
constructor(private service: Service<T, U>) {}
store(action: T): T {
if (this.db.has(action.type)) {
this.db.set(action.type, []);
}
this.db.get(action.type).push(action);
this.service.exec(action);
return action;
}
}
enum ActionType {
Call
}
interface Action extends Typed<ActionType>{
type: ActionType;
}
interface CallAction extends Action {
context: any;
}
class ActionService implements Service<Action, ActionType> {
exec(action: Action) {
if (action.type === ActionType.Call) {
console.log('ActionType.Call', (<CallAction>action).context);
}
return action;
}
}
const service = new ActionService();
const store = new Store<Action, ActionType>(service);
store.store({
type: ActionType.Call
}); |
@DanielRosenwasser Over to you - we agreed that this should be allowed in the comparability relation assuming it can be reasonably spec'd. |
T
-constrained type variable to subtypes of T
TypeScript Version: 2.6.2
Code
Expected behavior:
I should use cast because CallAction extends Action
Actual behavior:
I have the following compilation error:
The text was updated successfully, but these errors were encountered: