Skip to content

"Index signature is missing", but only when the type is inferred #24748

Closed
@jamesknelson

Description

@jamesknelson

TypeScript Version: 3.0.0-dev.20180607

Search Terms:
Index signature missing inferred mapped types

Code

declare function map<FromValue>(
  from: Publisher<FromValue>,
  to: (props: FromValue) => any
);

declare function combine<CombinedValue>(children: {
  [K in keyof CombinedValue]: Publisher<CombinedValue[K]>
}): Publisher<CombinedValue>;


type Publisher<Value> = { value: Value; }
type Box<Value> = { data: Value }
type X = { a: string }
type Y = { b: number }

// ---

let a = combine({
  x: undefined as Publisher<Box<X>>,
  y: undefined as Publisher<Box<Y>>,
})
map(a, boxes => {
  // Index signature if missing in type { x: Box<X>, y: Box<Y> },
  let fail1: {
    [name: string]: Box<any>
  } = boxes

  // But not when type { x: Box<X>, y: Box<Y> } is specified manually
  // instead of inferred
  let pass1: {
    [name: string]: Box<any>
  } = boxes as {
    x: Box<X>;
    y: Box<Y>;
  }

  // And it can still be assigned to index-typed objects...
  let pass2: {
    [name: string]: any
  } = boxes

})

// Here `b` has the same type as the type inferred for `a`, but it works.
// The behavior must stem from inferred type.
let b: Publisher<{
  x: Box<X>,
  y: Box<Y>, 
}>
map(b, boxes => {
  let pass3: {
    [name: string]: Box<any>
  } = boxes
})

Expected behavior:

Should compile.

Given that boxes can be assigned to { [name: string]: any }, it feels like it should also be able to be assigned to { [name: string]: Box<any> }.

Actual behavior:

Fails with:

test.ts:24:7 - error TS2322: Type '{ x: Box<X>; y: Box<Y>; }' is not assignable to type '{ [name: string]: Box<any>; }'.
  Index signature is missing in type '{ x: Box<X>; y: Box<Y>; }'.

24   let fail1: {

Playground Link:

http://www.typescriptlang.org/play/#src=declare%20function%20map%3CFromValue%3E(%0D%0A%20%20from%3A%20Publisher%3CFromValue%3E%2C%0D%0A%20%20to%3A%20(props%3A%20FromValue)%20%3D%3E%20any%0D%0A)%3B%0D%0A%0D%0Adeclare%20function%20combine%3CCombinedValue%3E(children%3A%20%7B%0D%0A%20%20%5BK%20in%20keyof%20CombinedValue%5D%3A%20Publisher%3CCombinedValue%5BK%5D%3E%0D%0A%7D)%3A%20Publisher%3CCombinedValue%3E%3B%0D%0A%0D%0A%0D%0Atype%20Publisher%3CValue%3E%20%3D%20%7B%20value%3A%20Value%3B%20%7D%0D%0Atype%20Box%3CValue%3E%20%3D%20%7B%20data%3A%20Value%20%7D%0D%0Atype%20X%20%3D%20%7B%20a%3A%20string%20%7D%0D%0Atype%20Y%20%3D%20%7B%20b%3A%20number%20%7D%0D%0A%0D%0A%2F%2F%20---%0D%0A%0D%0Alet%20a%20%3D%20combine(%7B%0D%0A%20%20x%3A%20undefined%20as%20Publisher%3CBox%3CX%3E%3E%2C%0D%0A%20%20y%3A%20undefined%20as%20Publisher%3CBox%3CY%3E%3E%2C%0D%0A%7D)%0D%0Amap(a%2C%20boxes%20%3D%3E%20%7B%0D%0A%20%20%2F%2F%20Index%20signature%20if%20missing%20in%20type%20%7B%20x%3A%20Box%3CX%3E%2C%20y%3A%20Box%3CY%3E%20%7D%2C%0D%0A%20%20let%20fail1%3A%20%7B%0D%0A%20%20%20%20%5Bname%3A%20string%5D%3A%20Box%3Cany%3E%0D%0A%20%20%7D%20%3D%20boxes%0D%0A%0D%0A%20%20%2F%2F%20But%20not%20when%20type%20%7B%20x%3A%20Box%3CX%3E%2C%20y%3A%20Box%3CY%3E%20%7D%20is%20specified%20manually%0D%0A%20%20%2F%2F%20instead%20of%20inferred%0D%0A%20%20let%20pass1%3A%20%7B%0D%0A%20%20%20%20%5Bname%3A%20string%5D%3A%20Box%3Cany%3E%0D%0A%20%20%7D%20%3D%20boxes%20as%20%7B%0D%0A%20%20%20%20x%3A%20Box%3CX%3E%3B%0D%0A%20%20%20%20y%3A%20Box%3CY%3E%3B%0D%0A%20%20%7D%0D%0A%0D%0A%20%20%2F%2F%20And%20it%20can%20still%20be%20assigned%20to%20index-typed%20objects...%0D%0A%20%20let%20pass2%3A%20%7B%0D%0A%20%20%20%20%5Bname%3A%20string%5D%3A%20any%0D%0A%20%20%7D%20%3D%20boxes%0D%0A%0D%0A%7D)%0D%0A%0D%0A%2F%2F%20Here%20%60b%60%20has%20the%20same%20type%20as%20the%20type%20inferred%20for%20%60a%60%2C%20but%20it%20works.%0D%0A%2F%2F%20The%20behavior%20must%20stem%20from%20inferred%20type.%0D%0Alet%20b%3A%20Publisher%3C%7B%0D%0A%20%20x%3A%20Box%3CX%3E%2C%0D%0A%20%20y%3A%20Box%3CY%3E%2C%20%0D%0A%7D%3E%0D%0Amap(b%2C%20boxes%20%3D%3E%20%7B%0D%0A%20%20let%20pass3%3A%20%7B%0D%0A%20%20%20%20%5Bname%3A%20string%5D%3A%20Box%3Cany%3E%0D%0A%20%20%7D%20%3D%20boxes%0D%0A%7D)%0D%0A

Related Issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions