Description
TypeScript Version:
55cbdc9 (current master)
Code
type Props = { propA: number, propB: string, propC: number };
var p: Props = { propC: 0 }; // Not a Props, missing propA and propB. Error, as expected
var q: Props = { propA: 6, propB: "b", propC: 0 }; // Ok, is a Props
var r = { propA: 6, propB: "b", propC: 0 }; // Not annotated, but is a Props
var s = { propA : 6, propC: 0 }; // Not a Props, missing propB. Not annotated, so not an error
var t = { propC: "c" }; // Not a Props, propC is the wrong type. Not annotated, so not an error
// No type annotation on parameter
function Component({ propA = 5, propB = "a", propC }) {
console.log(propA, propB, propC); // propC is any, undesirable
}
Component(q); // No error, expected
Component({ propC: 0 }); // No error, expected
Component(r); // No error, expected
Component(s); // No error, expected
Component(t); // Error, expected
// Type annotation on parameter
function Component2({ propA = 5, propB = "a", propC }: Props) {
console.log(propA, propB, propC); // propC is number, desirable
}
Component2(q); // No error, expected
Component2({ propC: 0 }); // Error, propA and propB are missing
Component2(r); // No error, expected
Component2(s); // Error, propB is missing
Component2(t); // Error, expected
tsc -t es5 ./foo.ts
Expected behavior:
Component2({ propC: 0 })
and Component2(s)
compile even though their parameters don't have propA and propB from Props
, because Component2
default-initializes those parameters.
Actual behavior:
foo.ts(26,12): error TS2345: Argument of type '{ propC: number; }' is not assignable to parameter of type '{ propA: number; propB: string; propC: number; }'.
Property 'propA' is missing in type '{ propC: number; }'.
foo.ts(28,12): error TS2345: Argument of type '{ propA: number; propC: number; }' is not assignable to parameter of type '{ propA: number; propB: string; propC: number; }'.
Property 'propB' is missing in type '{ propA: number; propC: number; }'.
plus errors about p
and Component2(t)
which are expected.
The reason to add the annotation on Component2
is to get type information for the non-default-initialized property propC
.
Is there any downside to allowing Component2({ propC: 0 })
and Component2(s)
? Component2(t)
should of course still not be allowed. s
and { propC: 0 }
should still not be considered to be Props
for the purpose of type inference.
Otherwise the user has to make a new type for each such function based on what's default-initialized and what isn't, like type PropsForComponentFunction = { propA?: number, propB?: string, propC: number }
, and make sure the types match with the original Props
. (Or inline the whole type declaration into Component2
but that has the same drawback.)