Typescript: Types of property length are incompatible when extending tuple types.

Created on 7 Dec 2017  ·  6Comments  ·  Source: microsoft/TypeScript




TypeScript Version: [email protected]

Code

type UnionizeTuple<T extends [any]> = T[number];
type a = ['hi', 'there']
type b = UnionizeTuple<a>

Expected behavior:

b === 'hi' | 'there'

Actual behavior:

Type '["hi", "there"]' does not satisfy the constraint '[any]'.
  Types of property 'length' are incompatible.
    Type '2' is not assignable to type '1'

This is working as expected in all previous versions of typescript. Updated to the latest typescript@next this morning and this broke. I see why this happened, by being smarter about how we process tuples we can know at compile time the length of a tuple. But because there are not variadic kinds, there is no other way to accomplish the above (or much more complicated examples as I am using elsewhere).

Question

Most helpful comment

In your interface you have this:

arrayStrLanguagesSupported: [ {...} ]

This tells typescript that this property is a tuple (array with known length [1 in this case]) with one object in it. You instead should tell it to use an array type:

arrayStrLanguagesSupported: {...}[]

All 6 comments

This is due to #17765.
The following seems to work though:

type UnionizeTuple<T extends { readonly [x: number]: any }> = T[number];
type a = ['hi', 'there']
type b = UnionizeTuple<a>

That's clever. Looks like it works well in all of my cases in my main codebase as well. Thanks for your help!

I dont understand Andy's solution.

I too updated to latest TS and now I get this error:

export const AppConfigData: AppConfig = {
arrayStrLanguagesSupported :
[
{ strI18nLanguageCode : 'en-US', strTranslate : 'UI.i18n.en-US' },
{ strI18nLanguageCode : 'es-MX', strTranslate : 'UI.i18n.es-MX' }
],
configTest : 'I am a test from the config file',
}
.
.
.
ERROR in .../app.config.data.ts(11,14): error TS2322: Type '{ arrayStrLan
guagesSupported: [{ strI18nLanguageCode: string; strTranslate: string; }, { strI
18nL...' is not assignable to type 'AppConfig'.
Types of property 'arrayStrLanguagesSupported' are incompatible.
Type '[{ strI18nLanguageCode: string; strTranslate: string; }, { strI18nLang
uageCode: string; strTransl...' is not assignable to type '[{ strI18nLanguageCod
e: string; strTranslate: string; }]'.
Types of property 'length' are incompatible.

Type '2' is not assignable to type '1'.

export interface AppConfig {
arrayStrLanguagesSupported : [ { strI18nLanguageCode : string, strTranslate : string } ],
configTest : string,
fullName : string,
fullNamePe : string,
.
.
.

No idea how to fix this.

Any advice?

In your interface you have this:

arrayStrLanguagesSupported: [ {...} ]

This tells typescript that this property is a tuple (array with known length [1 in this case]) with one object in it. You instead should tell it to use an array type:

arrayStrLanguagesSupported: {...}[]

Awesome! Thanks . That fixed it :)

@andnp

thanks!

Was this page helpful?
0 / 5 - 0 ratings