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.
CodePudding user response:
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.
CodePudding user response:
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.
