Conditional variables in aws-nodejs-typescript template

I’m having some issues with the TypeScript template, specifically this:

  provider: {
    name: 'aws',
    runtime: 'nodejs12.x',
    memorySize: 256,
    timeout: 10,
    // @ts-ignore
    logRetentionInDays: '${self:custom.logRetention.${self:provider.stage}}',

I want to have the value be 3 days for dev, and 30 days for prod. Of course, TypeScript yells at me for using a string here, even though it’s completely legit and works fine.

Is there a better way to do conditional variables? If only self:provider.stage was injected into process.env, that would be incredibly useful.

Well, it’s not completely legit, since it’s not supposed to be a string. Sure, Javascript will auto-convert it to a number in many cases, but I guess you’re using TypeScript because you want strong typing?

Anyway, simply convert it to an integer. You can use parseInt(), Number(), or simply put a plus in front:
logRetentionInDays: +’{self:custom.logRetention.{self:provider.stage}}’

Alternatively, if you feel it really SHOULD accept a string (I, for one, definitely do not), make a bug report on the serverless/typescript Github repo, asking for widening of the allowed types in the interface.

Hmmm… You’re actually right. The string will be replaced by the actual value, but the config doesn’t know that until it has converted the value, so a string should be accepted.

Aside from using @ts-ignore, this also works, though it looks ugly:

logRetentionInDays: Number('${self:custom.env.LOG_RETENTION_DAYS}') as AWS['provider']['logRetentionInDays']

The as 3 | 30 is necessary because the logRetentionDays is typed as:

logRetentionInDays?: 1 | 3 | 5 | 7 | 14 | 30 | 60 | 90 | 120 | 150 | 180 | 365 | 400 | 545 | 731 | 1827 | 3653;

EDIT: Nope, apparently my alternate solution doesn’t work. Once you use Number() on it, it returns null for some reason. Strange, because Number('3') definitely does not equal null.