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.

index signature is missing when do object destructuring to separate variable

See original GitHub issue

TypeScript Version: 4.1.2

Search Terms: destructuring, index signature is missing

Expected behavior: it works

Actual behavior: when I do object destructuring to separate variable index signature is lost somewhere

Related Issues:

Code

type InitialIndexType = {
    key: string;
};

type FinalIndexType = Record<string, string | number | boolean | null | undefined>;

const runtimeInitialVariable: InitialIndexType = { key: 'value' };

// 1. ok, InitialIndexType is compatible with FinalIndexType
const runtimeFinalVariable: FinalIndexType = runtimeInitialVariable;

// 2. error with destructuring, but only when do it to separate variable
const { ...runtimeInitialVariable_2 } = runtimeInitialVariable;

const runtimeFinalVariable_2: FinalIndexType = runtimeInitialVariable_2; // Index signature is missing in type '{ key: string; }'.

// 3. ok with destructuring, without separate variable
const runtimeFinalVariable_3: FinalIndexType = { ...runtimeInitialVariable };

// 4. ok even if I copy&paste type from error message and cast destructured variable to it
const { ...runtimeInitialVariable_4 } = runtimeInitialVariable;

const runtimeFinalVariable_4: FinalIndexType = runtimeInitialVariable_4 as { key: string }; // also works as `as InitialIndexType`
Output
"use strict";
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
const runtimeInitialVariable = { key: 'value' };
// ok, InitialIndexType is compatible with FinalIndexType
const runtimeFinalVariable = runtimeInitialVariable;
// error with ...rest, but only when do ...rest to separate variable
const runtimeInitialVariable_2 = __rest(runtimeInitialVariable, []);
const runtimeFinalVariable_2 = runtimeInitialVariable_2;
// ok with rest, without separate variable
const runtimeFinalVariable_3 = Object.assign({}, runtimeInitialVariable);
// ok even if I copy&paste type from error message and cast ...rest variable to it
const runtimeInitialVariable_4 = __rest(runtimeInitialVariable, []);
const runtimeFinalVariable_4 = runtimeInitialVariable_4; // also works as `as InitialIndexType`

Compiler Options
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "alwaysStrict": true,
    "esModuleInterop": true,
    "declaration": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "moduleResolution": 2,
    "target": "ES2017",
    "jsx": "React",
    "module": "ESNext"
  }
}

Playground Link: Provided

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:9
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

5reactions
2A5Fcommented, Dec 29, 2020

Shorter code

let { ...obj } = { a: 1 }
let foo: Record<string, number> = obj
// ^
// Type '{ a: number; }' is not assignable to type 'Record<string, number>'.
//   Index signature is missing in type '{ a: number; }'.(2322)

let { a } = { a: 1 }
let foo: Record<string, number> = { a }
// ^ this ok

Playground

3reactions
paulboocockcommented, Mar 6, 2021

I’ve just bumped into this one as well. It feels to me like the destructured object should be assignable to Record<string, unknown>.

Perhaps interestingly, it turns out if you spread the object into a new one it works whilst the original does not 🀷🏻

const { prop1, ...rest } = { prop1: 'a string', prop2: 2 };
const options1: Record<string, unknown> = rest; // This doesn't work
const options2: Record<string, unknown> = {...rest}; // This does work
Read more comments on GitHub >

github_iconTop Results From Across the Web

Destructed object has no Index Signature but other object is fine
If I destructure an object and then attempt to pass it into a function with a Record<string, unknown> parameter, I receive an error...
Read more >
Destructuring and parameter handling in ECMAScript 6 - 2ality
ECMAScript 6 (ES6) supports destructuring, a convenient way to extract values from data stored in (possibly nested) objects and arrays.
Read more >
How to allow objects with certain types of keys, but not require ...
// Fails with "Index signature for type 'string' is missing in type 'Employee'" const t2: QueryParams = employee;
Read more >
Documentation - More on Functions - TypeScript
Some objects, like JavaScript's Date object, can be called with or without new . ... We do this by declaring a type parameter...
Read more >
typescript symbol as object key - Coach Yohanes G. Pauly
TypeScript allows symbols for keys in the index signatures since version 4.4 We can define multiple ... How do I remove a property...
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