-
Notifications
You must be signed in to change notification settings - Fork 12
Fix Object.extend
arguments not being type-checked
#25
Conversation
Ahh, structural typing strikes again! Thanks for fixing this. Given that the entire point of a static type system is to exclude code that's known to be invalid at compile time, having negative test cases seems like it would be really valuable. Otherwise it seems like it would be really easy to regress on things like this without realizing it. I know DT's tests don't include coverage for this kind of thing, but do you think it would make sense to augment the suite in this repo? |
I did experiment with negative test cases in my ember-types repo which preceded this repo: test runner / test case. Maybe we could work it in somehow and still be compatible with the DT structure. I think we'll need a custom test runner anyway: once we start shipping typings with ember addons, we'll need to test them somehow. I don't think DT's test suite will work for that. |
That custom runner is really nice! It would also be awesome to be able to annotate expressions with an expected inferred type, similar to your expected error codes. Today's |
They do have an API to walk the AST, maybe it could check that |
Cool. Looks like we could even pretty easily take it one step further and verify that the inferred type of the expression matches the passed type argument exactly with something like: sourceFile.forEachChild(function verifyTypeAssertions(node) {
if (ts.isCallExpression(node)) {
if (ts.isIdentifier(node.expression) && node.expression.text === 'assertType') {
const tc = program.getTypeChecker();
const expectedType = tc.getTypeFromTypeNode(node.typeArguments[0]);
const actualType = tc.getTypeAtLocation(node.arguments[0]);
console.log('expected:', tc.typeToString(expectedType), 'actual:', tc.typeToString(actualType));
}
} else {
node.forEachChild(verifyTypeAssertions);
}
}); |
|
types/ember/index.d.ts
Outdated
/** | ||
* Mixin needs to have *something* on its prototype, otherwise it's treated like an empty interface. | ||
*/ | ||
__ember_mixin__: never; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW the TS compiler itself uses the term brand
for this pattern, which they have sprinkled around pretty liberally e.g. https://github.com/Microsoft/TypeScript/blob/master/src/compiler/types.ts#L621
I wonder if we could implement the negative case as a function and handle it with the compiler API shouldNotCompile(`
Controller.extend({ needs: 42 });
`); Then the code would be ignored if you used a different test runner |
/cc @dfreeman
This is something I noticed after merging #11.
extend
lets you pass any argument, even if the types don't match the definition:It was caused by
MixinOrLiteral
:Since
Ember.Mixin
had nothing on its prototype, everyextend
invocation matches the first case.I don't think I can write a test for it because we would be checking that the code doesn't compile.