{"id":13847319,"url":"https://github.com/threehams/typescript-error-guide","last_synced_at":"2025-07-12T08:31:33.067Z","repository":{"id":44973550,"uuid":"180190720","full_name":"threehams/typescript-error-guide","owner":"threehams","description":"TypeScript quirks and limitations, with explanations and solutions.","archived":false,"fork":false,"pushed_at":"2022-02-18T17:08:33.000Z","size":3812,"stargazers_count":26,"open_issues_count":19,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-21T21:42:30.712Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://typescript-error-guide.netlify.com/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/threehams.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-08T16:35:41.000Z","updated_at":"2024-06-01T17:03:02.000Z","dependencies_parsed_at":"2022-09-22T14:50:35.415Z","dependency_job_id":null,"html_url":"https://github.com/threehams/typescript-error-guide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/threehams/typescript-error-guide","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threehams%2Ftypescript-error-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threehams%2Ftypescript-error-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threehams%2Ftypescript-error-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threehams%2Ftypescript-error-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/threehams","download_url":"https://codeload.github.com/threehams/typescript-error-guide/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threehams%2Ftypescript-error-guide/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264962223,"owners_count":23689765,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T18:01:16.692Z","updated_at":"2025-07-12T08:31:32.464Z","avatar_url":"https://github.com/threehams.png","language":"TypeScript","readme":"# The TypeScript Error Guide\n\nTypeScript makes some normally complex tasks very easy, but it can make some seemingly-simple tasks more difficult,\n\n## Some things that were hard: now easy!\n\nChange an API? Change the type and you'll see everywhere you need to update. Need to rename something used in 500 places? Hit F2 and rename.\n\n## Some things that were easy: now hard.\n\nTypeScript actively discourages highly-dynamic code, redefining variables at will, and APIs that put a lot of meaning into strings. What do these look like?\n\n```tsx\nconst sizes = {\n  \"size-sm\": 1,\n  \"size-md\": 2,\n  \"size-lg\": 3,\n};\n\nconst getSize = (size: \"sm\" | \"md\" | \"lg\") =\u003e {\n  return sizes[`size-${size}`];\n};\n```\n\nThis site is all about letting you know about these limitations _without_ all the type-system jargon you'll normally see.\n\n# Diagnostic Codes\n\nTypeScript has a code for every error, such as `ts(2741)`. While the error message may look very different each time, the underlying problem is the same.\n\nIf you're hitting a problem, search for that code within this page.\n\n# For Site / Application Developers\n\n## I'm trying to start with an empty object and add properties one by one, and TypeScript gives me errors no matter what I do. I've given up and `// @ts-ignore`d them.\n\nWhen you create an empty object, there's just no good way for TS to ensure that all properties have been added _after_ the object has already been specified. Don't worry, though - there are lots of ways to accomplish this, and one of them is very concise as well! See: [Build Up Object](examples/build-up-object.ts).\n\nDiagnostic codes: `ts(2339)`, `ts(2741)`\n\n## What's this `never` type?\n\nThis is covered in the new handbook under the [never type](https://microsoft.github.io/TypeScript-New-Handbook/chapters/more-on-functions/#never).\n\nAdditionally, arrays start out as `never[]` when the type cannot be inferred. See: [Never](examples/never.ts)\n\n## Why isn't TypeScript showing errors on extra properties I have on an object?\n\nTypeScript has a system called \"excess property checking\" which is a great tradeoff between type safety and developer experience... provided you know how it works. Luckily, it's pretty simple. See: [Excess Property Checking](examples/excess-property-checking.ts).\n\n## How can I get a function to accept an object with a couple extra properties? My code works fine!\n\nSame question as above! Understanding [Excess Property Checking](examples/excess-property-checking.ts) will let you intentionally bypass this check where needed.\n\n## I used `filter` but TS errors and says that something could be null/undefined.\n\nA nullable type is a union type, such as `string | null`. To narrow types in a function like `filter`, an extra annotation is needed for now (TypeScript might make an exception here in the future). See: [Filter and Reduce](examples/filter-reduce.ts).\n\n## Why can't I use `reduce` without errors on the result object?\n\nYou can! However, creating an empty object and building it up one property at a time isn't something that can really ever be checked for safety. A simple type assertion is typically all you need. A few different approaches are available at [Filter and Reduce](examples/filter-reduce.ts).\n\n## I have an array of mixed object types. Why can't I narrow based on whether or not a property exists?\n\nYou can! You just have to use an `in` check to opt in to less-strict checking of properties. See the tradeoffs and other solutions in [Type Guards](examples/type-guards.ts).\n\n## I checked if something is null, and now TypeScript is complaining that something might be null.\n\nThis is usually an example of TS being especially careful with callbacks, as they may or may not be called synchronously. See: [Type Widening](examples/type-widening.ts).\n\n## Is it OK to have an object function argument with a bunch of optional properties?\n\nMaybe! If all the options really are independently optional, that's fine. However, you may have a couple properties which are _exclusive_ of one another. Think of a function that must accept either \"a\" or \"b\", but cannot accept both at once. If this covers your case, [Dependent Properties](examples/dependent-properties.ts) can help you.\n\n## I'm using a library, and I seem to need to manually type everything for it.\n\nThis can be one of a few issues.\n\nIf the library you're using involves two functions that quietly pass information between each other between imports (example: redux `createStore()` and react-redux `connect()` or `useSelector()`), you might be interested in the [Extending Modules](examples/extending-modules.ts) section. This can let you define types _once_ instead of on every usage.\n\nIf this isn't the case, your library is likely set up to accept generics. These are like function arguments, but for types. The syntax for these involves angle brackets (`\u003c\u003e`) and can be tricky, so see [Generics](examples/generics.ts) for details.\n\nFinally, some libraries just don't have very good type definitions available, or are so dynamic that creating good library definitions isn't possible, or require types which TypeScript just can't support yet. This is rare, but an example is the [humps](https://github.com/domchristie/humps) library which converts all keys of an object from snake_case to camelCase. For these instances, you might want to use a [Type Assertion](examples/type-assertion.ts). This ties into knowing [when to bail out of types](examples/when-to-bail-out.ts).\n\n## My function accepts string | number as a type and returns string | number. I know I gave it a string but now I have to check for numbers every time.\n\nYou're looking for [Generics](examples/generics.ts). These allow you to change the return value based on the arguments. Think of them like function arguments, but for types.\n\n## Hey! I used a generic like you said, and now I'm getting type errors inside my function.\n\nRight! Generics accept anything by default, so your `add()` function suddenly needs to accept arrays, objects, and `null`. You might want to restrict which types you accept using [Bounded Type Parameters](examples/bounded-type-parameters.ts).\n\n## I'm using Object.keys() or Object.entries() and there's some index signature error. Why is the key ending up as a `string`?\n\nThis one trips up everyone at some point. There's an explanation at [Object.keys and Object.entries](examples/object-keys-and-entries.ts). Don't worry, there's a reason for it - and a few ways to opt-in to the behavior you want.\n\n## I don't control the object being used. How do I use the `object` type?\n\n## How can I tell TypeScript about a global variable that exists without using @ts-ignore or `any`?\n\nYou're looking for the jargony `ambient context` and `ambient declaration`. When you put `declare` in front of a function, constant, or module, you are saying \"trust me, this exists, and is of this type.\" This is especially confusing when looking at the differences between .d.ts and .ts files, so see [Types without implementations](examples/types-without-implementations.ts).\n\n# React-Specific Errors\n\nFor most React errors, there's an excellect [cheat sheet](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet) for using React with TypeScript. This is updated constantly with new information.\n\n## How do I work with `children`? All I get are errors trying to access anything.\n\nA React child is union of many, many possible things which cannot be narrowed except by complex type guards at every object depth. When iterating over children, it's probably best to use `any` and distrust the existence of any property:\n\n```tsx\nconst containsDiv = React.Children.toArray(children).some((child: any) =\u003e {\n  return child?.type?.displayName === \"Header\";\n});\n```\n\n## I'm getting a \"not a constructor function for JSX elements\" error.\n\nYou're returning something from a function component which React doesn't accept, likely `undefined`. Your code might be fine now, but if it ever hits that `undefined` case, you'll get a runtime error.\n\n```tsx\nimport React from \"react\";\n\ninterface Props {\n  text?: string;\n}\nconst Button = ({ text }: Props) =\u003e {\n  return text \u0026\u0026 \u003cbutton\u003e{text}\u003c/button\u003e;\n};\n```\n\nIf `text` isn't supplied to Button, it'll return the current value of `text` (which is `undefined`). React currently throws in this case.\n\nTo get a better error message, add a return type annotation to your function component of either `ReactElement` or `ReactElement | null`. This will move the error to the return statement:\n\n```tsx\ninterface Props {\n  text?: string;\n}\nconst Button = ({ text }: Props): ReactElement | null =\u003e {\n  return text ? \u003cbutton\u003e{text}\u003c/button\u003e : null;\n};\n```\n\n# For Library Authors\n\n## I want to make my library work with TypeScript. What's all this .d.ts nonsense?\n\nd.ts files are interesting. They allow you to declare the external API for your library without needing to specify\n\nThis can be challenging.\n\n## How do I test types?\n\nIf you're writing library definitions, [Testing Types](examples/testing-types.ts) can help you, by using the [Conditional Type Checks](https://github.com/dsherret/conditional-type-checks) library.\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthreehams%2Ftypescript-error-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthreehams%2Ftypescript-error-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthreehams%2Ftypescript-error-guide/lists"}