Closed
Description
TypeScript Version: 2.0.3
Code
// A *self-contained* demonstration of the problem follows...
// this is from redux-typed
abstract class Action {
type: string;
constructor() {
this.type = this.type;
}
}
// this is from redux-typed
interface ActionClass<TAction extends Action> {
prototype: TAction;
}
// we use this any-typed base class so we don't have to specify TAction and it can be polymorphic
abstract class ReductionBase<TState> {
action: any;
newValues: {(a):TState};
}
// this represents a potential reducer function to execute on an action
class Reduction<TState, TAction extends Action> extends ReductionBase<TState> {
action: ActionClass<TAction>;
newValues: (a:TAction) => TState;
constructor(actionClass: ActionClass<TAction>,
newValues: (action: TAction) => TState ) {
super();
this.action = actionClass;
this.newValues = newValues;
}
}
// this abstract class should specify that the type to Reduction<TState, TAction> is its TState
abstract class Store<TState> {
memberVariable: TState; // this is just included to make a point later
// this function is to instantiate compatible Reductions that match TState
reduction<TAction extends Action>(actionClass: ActionClass<TAction>,
newValues: (action: TAction) => TState)
: Reduction<TState, TAction> {
return new Reduction(actionClass, newValues);
}
}
// type to become TState
interface ConcreteState {
stateItemOne?: string[];
stateItemTwo?: string[];
stateItemThree?: string[];
}
// type to become TAction
class ConcreteAction extends Action {
actionItemOne?: string[];
actionItemTwo?: string[];
}
// implement Store<T> for ConcreteState
class ConcreteStore extends Store<ConcreteState> {
reducer(state, action) {
var reductionVar = this.reduction(
ConcreteAction, (a) => {
return {
// in Visual Studio 2015, I get compile-time type checking
// and auto-complete in this body for members of a, but NOT
// for members of this return type!
stateItemOne: a.actionItemNonexistent, // #1: this fails, as expected :)
stateItemNonexistent: a.actionItemTwo // #2: this does NOT fail :(
// Interestingly enough, this TypeScript Playground does go as far as
// to provide the correct auto-completion for these members, but the
// VS2015 intellisense does not even do that. :(
}
});
this.memberVariable = {
stateItemNonexistent: [] // #3: this fails with the error "Object literal may
// only specify known properties", which was my expected
// slash desired behavior at #2.
}
}
}
Expected behavior:
- Statement at "Updating some tests for resolved bugs #2" should check the
return {
object literal against theConcreteState
type, and display a compilation error, exactly as it does at "Revert "Updating some tests for resolved bugs" #3". - Visual Studio 2015 should provide intellisense/auto-completion behavior for members of the return type at "Suggestion: 'protected' modifier #1/Updating some tests for resolved bugs #2", i.e. suggesting
stateItemTwo
andstateItemThree
Actual behavior:
- Statement at "Updating some tests for resolved bugs #2" does not fail the type check (despite the type of the resulting
reductionVar
being correctly detected and displayed asReduction<ConcreteState, ConcreteAction>
). - Intellisense/auto-completion behavior of
stateItemTwo
/Three
occurs on the TypeScript Playground, and in Visual Studio Code 1.4, but does NOT occur in Visual Studio 2015 (update 3 with TypeScript 2 installed).