简体   繁体   中英

How can I tell Typescript to use the default value when an empty string is provided as function parameter?

In Typescript, when assigning a default value to a parameter of type string , the empty string counts as something and the default value is not used.

This makes sense, but in some cases, I'd like to change that:

function greet (name?:string = 'visitor') {
  console.log(`Hello ${name}`)
}
greet('Gromit') // logs "Hello Gromit"
greet() // logs "Hello visitor"
greet('') // logs "Hello " <--- How can I get the default value in this case too?

Does Typescript perhaps have a feature, which I am not finding, to help define when I want the default value to apply?

I have been using what I consider to be a workaround, for now:

const defaultName = 'visitor'
function greet (name?:string = defaultName) {
  const finalName = name || defaultName
  console.log(`Hello ${finalName}`)
}

But I would rather use something cleaner and more idiomatic to Typescript and I would be surprised if a better pattern doesn't exist.

To be clear, I would have expected to find a way to do this within that part of the code responsible for defining the function parameters: function greet (/* here */) {}

The proposed solutions introduce code outside of this section the same as I do in my workaround.

Thanks for any pointers!

There's no way to define this condition inside the function arguments. The cleanest way I can think of is simply to check and replace the value inside the function body:

function greet(name?: string) {
  name = name || 'visitor'
  // other code
}

A better pattern doesn't exist, because it would conflict with the perfectly reasonable behavior that "" overrides the default non-empty value.

You have two different ways of specifying default-like behavior, one of which is an absent value, and one of which provides a value if passed an empty/falsy value. These might happen to result in the same value, but there isn't a more-concise pattern to represent this in the function signature or implementation.

The only modification I would make to MaartenDev and Vojtěch Strnad's answers would be to document the default value in JSDoc, which might accomplish your goal of IDE integration. (Unfortunately, even then JSDoc's optional/default value support [name="visitor"] isn't visible in TypeScript Playground or VSCode.)

/**
 * Greets a person.
 *
 * @param [name] Name to greet. "visitor" if falsy or absent.
 */
function greet(name?: string) {
  name = name || 'visitor'
  // other code
}

Playground Link

Observation: As you are initializing a default value to name parameter, it makes that parameter optional. Hence, no need to add Question mark (?) explicitly as it will through a below compilation error.

Parameter cannot have question mark and initializer.

Regarding the issue you are facing, You can get rid from that by using Conditional (ternary) operator

function greet (name:string = 'visitor') {
    console.log(`Hello ${name}`)
}
 
greet('' ? '' : undefined) // Hello visitor

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM