question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Function-type props broken in TypeScript

See original GitHub issue

Version

2.5.22

Reproduction link

https://jsfiddle.net/keegan_openbay/gehkx7pf/10/
https://jsfiddle.net/keegan_openbay/018rs3ae/11/

(More explanation in the fiddle, but keep in mind that JSFiddle doesn’t show TS errors)

Steps to reproduce

  1. Declare a prop of type Function, and with a default function that returns some value; e.g.,
// ...
  props: {
    fooFn: {
      type: Function,
      default: () => true,
    },
  },
// ...
  1. Try to use that function elsewhere in your component options; e.g.,
// ...
  methods: {
    useFooFn(): void {
      const bar = this.fooFn();
      // ...
    },
  },
// ...

What is expected?

type FooFn = typeof this.fooFn; // Function
this.fooFn(); // no errors

What is actually happening?

type FooFn = typeof this.fooFn; // boolean | Function
this.fooFn();
// Cannot invoke an expression whose type lacks a call signature.
// Type 'boolean | Function' has no compatible call signatures.

Vue version: 2.5.22 TypeScript version: 3.0.3

tsconfig.json:

{
  "compilerOptions": {
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": ["es7", "dom"],
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": true,
    "target": "es5",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "baseUrl": "./app/javascript",
    "noImplicitThis": true
  },
  "include": [
    "app/javascript/**/*.ts",
    "app/javascript/**/*.tsx",
    "app/javascript/**/*.vue"
  ],
  "exclude": [
    "**/*.spec.ts",
    "node_modules"
  ],
  "compileOnSave": false
}

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:24
  • Comments:18 (3 by maintainers)

github_iconTop GitHub Comments

9reactions
pikaxcommented, Apr 23, 2019

if you annotate with the PropType<> it should work, this was a fix on https://github.com/vuejs/vue/pull/9733

const Example = Vue.extend({
	template: `
  	<button @click="doSomethingWithFoo()">
    	<slot></slot>
    </button>
  `,

  props: {
    // original issue
    fooFn: {
      type: Function as PropType<()=>string>,
      default: () => { return 'hey this is the default return value'; },
    },


     returnsAnObject: {
      type: Function as PropType<()=>object>,
      default: () => ({}),
    }
  },

  methods: {
    doSomethingWithFoo(): void {
      const obj = this.returnsAnObject(); //obj is object
    	const bar = this.fooFn(); // bar is string
  
      alert(bar);
    },
  },
});

there’s an PR https://github.com/vuejs/vuejs.org/pull/2068 to update docs

1reaction
kjleitzcommented, Mar 20, 2020

This is still broken, even with "strict": true; can’t use a default for a function-type prop. A more complete example:

const ComponentWithFunctionProps = Vue.extend({
  props: {
    functionProp: {
      type: Function,
      default: () => true,
    },
    functionPropWithBooleanReturnType: {
      type: Function as PropType<() => boolean>,
      default: () => true,
    },
    booleanProp: {
      type: Boolean,
      default: true,
    },
    booleanPropWithFunctionDefault: {
      type: Boolean,
      default: () => true,
    },
  },
  methods: {
    test(): void {
      // ERROR!
      // (property) functionProp: boolean | Function
      // -------------------------------------------
      // This expression is not callable.
      //   No constituent of type 'boolean | Function' is callable.ts(2349)
      this.functionProp();

      // ERROR!
      // (property) functionPropWithBooleanReturnType: boolean | (() => boolean)
      // -----------------------------------------------------------------------
      // This expression is not callable.
      //   Not all constituents of type 'boolean | (() => boolean)' are callable.
      //     Type 'false' has no call signatures.ts(2349)
      this.functionPropWithBooleanReturnType();

      // const foo: boolean
      const foo = this.booleanProp;

      // const bar: boolean
      const bar = this.booleanPropWithFunctionDefault;
    },
  },
});

I submitted a fix for this in https://github.com/vuejs/vue/pull/11223.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Creating a function type that returns argument object with ...
TypeScript allows extraneous properties by default, so you shouldn't need any additional handling to allow those on the return type.
Read more >
Handle Props in React in TypeScript
In this article, I will describe some issues you may encounter making illegal props unrepresentable in React. #Handle union of functions; #Use component ......
Read more >
TypeScript errors and how to fix them
A list of common TypeScript errors and how to fix them.
Read more >
Passing Functions in React with TypeScript - Pluralsight
In this component, we create an interface that defines what kind of props our Toggle component should receive. We are expecting only one...
Read more >
React prop types with TypeScript - how to have a function type?
Coding example for the question React prop types with TypeScript - how to have a function type?-Reactjs.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found