Reputation: 21
I'm trying to utilize a named tuple (in this instance AnniversaryPropertyConfig
) to describe a function argument in the following simplified code.
interface AnniversaryParameters {
value?: 'date-and-or-time' | 'text';
altid?: number | string;
calscale?: 'gregorian';
}
type AnniversaryPropertyConfig = [value: string, parameters?: AnniversaryParameters];
function main(config: AnniversaryPropertyConfig) {
return config;
}
const config = ['19960415', { value: 'text' as const }];
main(config);
However I keep receiving the following error: "Target requires 1 element(s) but source may have fewer.(2345)" I've tried to apply as const
assertions to the config
array and its values but to no avail. The error does go away if I typecast the config
variable to the AnniversaryPropertyConfig
type. But I feel like this is something that TypeScript should be able to infer without assistance.
For reference a link to an applicable TypeScript Playground can be found here.
Upvotes: 2
Views: 5371
Reputation: 55604
Your problem is that you defined AnniversaryPropertyConfig
as a tuple : [value: string, parameters?: AnniversaryParameters]
Arrays are never infered as tuple, so you have to explicitly assert the type.
interface AnniversaryParameters {
value?: 'date-and-or-time' | 'text';
altid?: number | string;
calscale?: 'gregorian';
}
type AnniversaryPropertyConfig = [value: string, parameters?: AnniversaryParameters];
function main(config: AnniversaryPropertyConfig) {
return config;
}
const config: AnniversaryPropertyConfig = ['19960415', { value: 'text' }];
main(config);
And do yourself a favor, avoid by all means type assertions like myVar as MyType
. It's never a good idea.
Upvotes: 1
Reputation: 13700
The only way I found to get rid of the error was to do this:
const config = ['19960415', { value: 'text' }] as AnniversaryPropertyConfig;
...or...
const config: AnniversaryPropertyConfig = ['19960415', { value: 'text' }];
From what I can guess, TypeScript's type inference sees ['19960415', { value: 'text' }]
as an array that could have strings in any position in the array, or objects that match { value: 'text' }
at any position in the array. So the inferred type doesn't have any enforced order for the array elements, making it too broad a type to automatically agree with AnniversaryPropertyConfig
.
Upvotes: 0