- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.1k
Description
After reading the Comparing two functions section of the handbook I got myself pretty confused and concerned. I have an example below that I think (taken to the prepare-for-duck-typing-extreme) means I should code every class's method as if all of its parameters are optional (even though they're not defined as such).
TypeScript Version:
1.8.10 / next (1.9.0-dev.20160624-1.0)
Code
(function () { "use strict";
class C1 { one(...hi: string[]) { } }
class C2 { one(hi: string) { hi.length; } }
function Test() {
    const c2 = new C2();
    const c2as1: C1 = c2;   // BAD assignment
    // TypeError: Cannot read property 'length' of undefined
    c2as1.one();            // BAD execution
    // error TS2346: Supplied parameters do not match any signature of call target.
    //c2.one();
    // error TS2345: Argument of type 'undefined' is not assignable to parameter of type 'string'.
    //                 Happens once you enable TypeScript 2.0's --strictNullChecks.
    //c2as1.one(void 0);
    //c2.one(void 0);
}
})();Actual behavior:
I have to remember to write run-time checking of typeof hi === "string" ? hi.length : 0 instead of the simple/easy hi.length inside my C2#one(hi: string) method to prevent against a TypeError.
Expected behavior:
I'd love for there to be some way for TypeScript to stop the BAD assignment line above; maybe one that turns off 'discarding' parameters altogether?
The defense given for discarding parameters is a signature like Array#forEach -- where callers commonly omit the 2nd/3rd parameters to the callbackfn. That doesn't make sense to me though, why isn't the *.d.ts for Array#forEach just defined as:
forEach(callbackfn: (value?: T, index?: number, array?: T[]) => void, thisArg?: any): void;Instead of how it is?
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;Maybe my targeting of parameter discarding is too strong, but it really seems like there should be some way to configure TypeScript to block the assertion of a C2 instance to a C1 interface without requiring me to just write better code like:
class betterC1 { one(hi: string, ...restHi: string[]) { } }