TypeScript Version: Version 2.1.0-dev.20160801
Code
class A {
f({x}: {x?: boolean} = {}) {};
}
class B extends A {
f({x, y}: {x?: boolean, y?: boolean} = {}) {};
}
with strictNullChecks the code is accepted and the following .d.ts produced
declare class A {
f({x}?: {
x?: boolean;
}): void;
}
declare class B extends A {
f({x, y}?: {
x?: boolean;
y?: boolean;
}): void;
}
Expected behavior:
Since the original code is accepted, the .d.ts file should also be accepted.
Actual behavior:
When passed to tsc with strictNullChecks the .d.ts in question produces the error
test.d.ts(7,8): error TS2459: Type '{ x?: boolean | undefined; y?: boolean | undefined; } | undefined' has no property 'x' and no string index signature.
test.d.ts(7,11): error TS2459: Type '{ x?: boolean | undefined; y?: boolean | undefined; } | undefined' has no property 'y' and no string index signature.
Confusingly, if you removed the inheritance the signature for B is accepted.
In general, I am surprised that TypeScript keeps any mention of destructuring in the .d.ts. In my mind that is part of the implementation of the function and has no relevance to the function signature. What would happen if TS plainly emits - f(a?: {x?: boolean;}): void;.
Definitely looks like a bug.
In general, I am surprised that TypeScript keeps any mention of destructuring in the .d.ts. In my mind that is part of the implementation of the function and has no relevance to the function signature. What would happen if TS plainly emits - f(a?: {x?: boolean;}): void;.
I actually agree, and that was our original intent. However, a key issue is that we have no good parameter name to substitute in place of a destructuring pattern. You'd end up with auto-generated names like _1 or p1 instead of the arguably more informative {x, y}.
@sheetalkamat can you take a look? Thanks!
I'm using TS 2.21, when StrickNullChecks turned on, same thing happened to angular 4.0rc1 in file @angular\forms\typings\src\model.d.ts. TypeScript generates following code that causes compile error TS2459 (has no property 'x' and no string index signature)
reset(formState?: any, {onlySelf, emitEvent}?: {
onlySelf?: boolean;
emitEvent?: boolean;
}):
Quite a serious bug - made angular 4.1 completly break it's promise of strict null checks functionality.
@mmc41 Well, angular has been breaking promises left and right.
Just hit this as per apollographql/apollo-link-state#158
Workaround for now is to just destructure inside the function body instead of in the function arguments, but that essentially means that any library that exposes typings and use destructuring + defaults in function arguments will break strict nulls. That's kind of serious, especially since it seems to happen in typings that are very difficult to override in an app's custom .d.ts files.
This seems to be fixed in latest build
Most helpful comment
Quite a serious bug - made angular 4.1 completly break it's promise of strict null checks functionality.