microsoft / microsoft/TypeScript

Suggestion: Type annotations and interfaces for function declarations

Open
#22,063 41 comments 131 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Has Repro In Discussion Suggestion
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

Currently in TypeScript, function declarations cannot be typed in the same way as function expressions, e.g. this function can implement the React.FC interface:

interface TestProps {
    message: string
}

const Test: React.FC<TestProps> = ({ message }) => {
    return <div>{message}</div>
}

But this function can't, at least not directly:

function Test({ message }: TestProps) {
    return <div>{message}</div>
}

This becomes more of an issue if you try to add properties to the function object:

Test.defaultProps = {
    message: 'hi'
}

It seems that currently the only way to specify the type for the function object in the second example is to create a new variable:

const AliasForTest: React.FC<TestProps> = Test
AliasForTest.defaultProps = {
    message: 'hi'
}

This seems like kind of an ugly workaround, so it seems that the current idiom is to just prefer arrow functions for cases like this. But this leads to inconsistency on teams that generally prefer function declarations over const expressions for top-level functions. Personally I find it more readable to see the word "function" for top-level functions rather than seeing "const", which is generally already all over the place in the code. There is even an ESLint rule for teams that share my preference (although I don't think it's been ported to TSLint yet): https://eslint.org/docs/rules/func-style. In any case, I have seen others express similar views and other codebases (including some from Facebook and Apollo, for example) that still prefer the "function" keyword for top-level functions.

However, stylistically it's also a problem if top-level functions are declared some places as declarations (using function) and in other places as expressions (using const). But for those who desire consistency, TypeScript is basically forcing the use of expressions, due to the issues described above.

This is far from being a top priority of course, but I was surprised to see that TypeScript didn't provide some equivalent typing syntax for function declarations. It would be great if this could be considered for a future version (even if far in the future). Thanks for reading!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No repository files or tests are named. Start by reviewing how TypeScript currently types function declarations versus expressions, then clarify the desired declaration syntax and its behavior for properties such as defaultProps. Done requires an agreed design plus implementation and tests accepted by maintainers.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.