TypeScript: Regression when using indexed type depending on function argument as return type

TypeScript Version: 3.5.1

Search Terms:

Code

interface Foo {
	prop1: { value: number }[];
	prop2: string[];
}
function getFoo<T extends keyof Foo>(key: T): Foo[T] | undefined {
	if (key === "prop1") {
		return [{ value: 1 }]; // Error here
	}
}
const bar = getFoo("prop1"); // has correct type

Expected behavior: No error. This used to work in 3.4.5

Actual behavior:

Type '{ value: number; }[]' is not assignable to type 'Foo[T]'.
  Type '{ value: number; }[]' is not assignable to type '{ value: number; }[] & string[]'.
    Type '{ value: number; }[]' is not assignable to type 'string[]'.
      Type '{ value: number; }' is not assignable to type 'string'.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 24 (10 by maintainers)

Most upvoted comments

@RyanCavanaugh Don’t you think cases like this should work though? Is this unsound?

interface ConfigMap {
	Number: number;
	String: string;
	Boolean: boolean;
}

const MyNumber: number = 0;
const MyString: string = "foo";
const MyBool: boolean = false;

export function GetConfiguration<K extends keyof ConfigMap>(key: K): ConfigMap[K] {
	if (key === "Number") {
		return MyNumber;
	} else if (key === "String") {
		return MyString;
	} else if (key === "Boolean") {
		return MyBool;
	}
}

const a = GetConfiguration("Boolean");
const b = GetConfiguration("Number");
const c = GetConfiguration("String");

This wasn’t properly checked in 3.4:

interface Foo {
	prop1: { value: number }[];
	prop2: string[];
}
function getFoo<T extends keyof Foo>(key: T): Foo[T] | undefined {
  if (key === "prop1") {
        // Oops!
		return ["foo"];
	}
}
const bar = getFoo("prop1");