error TS2551: Property 'lenght' does not exist on type 'string[]'. Did you mean 'length'? is TS2339 with a spelling suggestion: the property is not declared, but a declared one is close enough in spelling that the checker names it.
In plain JavaScript the same typo returns undefined at run time, which then surfaces somewhere else; items.lenght is a common way to get an empty list rendered as if it were full.
At a glance
| Code | TS2551 |
|---|---|
| Message | Property '{0}' does not exist on type '{1}'. Did you mean '{2}'? |
| TypeScript's category | error |
| Listed under | Unknown names and members |
| Turned on by | No option: every checked file reports it |
| In .js files | Reported when the file is checked: checkJs in jsconfig.json, or // @ts-check at the top of the file |
The message is TypeScript's own text from its diagnostic messages file (Apache-2.0); {0}, {1} and {2} are filled in by tsc for each error.
What it looks like
/** @param {string[]} items */
export function itemCount(items) {
return items.lenght;error TS2551: Property 'lenght' does not exist on type 'string[]'. Did you mean 'length'?
}
/** @param {string} url */
export async function contentType(url) {
const response = await fetch(url, { method: "HEAD" });
return response.heders.get("content-type");error TS2551: Property 'heders' does not exist on type 'Response'. Did you mean 'headers'?
}
/** @param {string} url */
export async function loadCart(url) {
const response = await fetch(url);
return response.josn();error TS2339: Property 'josn' does not exist on type 'Response'.
}jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} What causes it
- A typo in a property or method name (
lenght,heders). - A name from another API that is close to the real one (for example a plural for a singular).
How to fix it
Use the suggested name
Editors that run TypeScript's language service offer the suggestion as a quick fix (Change spelling to 'length'). Check it is the property you meant before accepting it.
/** @param {string[]} items */
export function itemCount(items) {
return items.length;
}
/** @param {string} url */
export async function contentType(url) {
const response = await fetch(url, { method: "HEAD" });
return response.headers.get("content-type");
}
/** @param {string} url */
export async function loadCart(url) {
const response = await fetch(url);
return response.json();
}jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} Or declare the property
If the property is real and the type is missing it, fix the type as for TS2339: extend the @typedef, or add an interface declaration for a global object.
Gotchas
- Suggestions depend on how far the typo is from a real name. Short names with swapped letters often get none: in the example,
response.josn()is plain TS2339 whileresponse.hedersgets the hint. - The suggestion can be wrong when two members are similar; reading the type in a hover is quicker than trusting the hint.
Sources
- Everyday Types: Object Types · TypeScript handbook
- diagnosticMessages.json (TypeScript 5.9.3) · TypeScript on GitHub
Last reviewed 20 October 2026.