Skip to content

withDefaults() infers wrong type when using a default value factory function #4480

@HoPGoldy

Description

@HoPGoldy

Version

3.2.6

Reproduction link

github.com - vue3-issue-default-function-prop

Steps to reproduce

I have the following functions and the same type definitions in service.ts, This function simply returns a string:

export const defaultFunc = function(): string {
    return 'result'
}

export type DefaultFunc = () => string

Then import them in a setup script and set props, defaults using defineProps and withDefault:

<script setup lang="ts">
import { defaultFunc } from './service';
import type { DefaultFunc } from './service';

interface Props {
  fetchData?: DefaultFunc
}

// set default function prop
const props = withDefaults(defineProps<Props>(), {
  fetchData: defaultFunc
});

// print default prop function value
console.log('======> default prop fetchData:', props.fetchData);
</script>

call this component and does not pass the prop fetchData, then check the console output of the web page.

What is expected?

Then console print the function itself:

======> default prop fetchData: ƒ () {
  return "result";
}

What is actually happening?

the console prints the return value of the default function, not the function itself.

======> default prop fetchData: result

How to resolve the issue

  • Passing in the function when the component is called.

  • Write directly to the type of the default function instead import it:

<script setup lang="ts">
import { defaultFunc } from './service';

interface Props {
  fetchData?: () => string // <=============== look here
}

const props = withDefaults(defineProps<Props>(), {
  fetchData: defaultFunc
});

console.log('======> default prop fetchData:', props.fetchData);
</script>

Then console will print the function itself correctly:

======> default prop fetchData: ƒ () {
  return "result";
}

Other ways to trigger the issue

Use typeof to get the function type and use it in the props interface:

<script setup lang="ts">
import { defaultFunc } from './service';

interface Props {
  fetchData?: typeof defaultFunc // <=============== look here
}

const props = withDefaults(defineProps<Props>(), {
  fetchData: defaultFunc
});

console.log('======> default prop fetchData:', props.fetchData);
</script>

More information

  • The default prop function in the <template> correctly returns the function itself.

  • The same issue occurs when the default prop function return a Promise.

  • Here is my npx envinfo --binaries --system:

System:
    OS: Windows 10 10.0.18363
    CPU: (8) x64 Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz
    Memory: 6.18 GB / 15.77 GB
Binaries:
    Node: 12.16.1 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.10 - C:\Program Files\nodejs\yarn.CMD
    npm: 6.13.4 - C:\Program Files\nodejs\npm.CMD
  • the example above was created using yarn create vite with typescript.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions