microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.75k stars 12.46k forks source link

Type compatibility in nested interfaces #48472

Closed gooverdian closed 2 years ago

gooverdian commented 2 years ago

Bug Report

🔎 Search Terms

type compatibility compatibility nested

sry, not many ways I can rephrase that, cos English is not my native language

🕗 Version & Regression Information

⏯ Playground Link

Playground link with relevant code

💻 Code

import React, { FC } from 'react';

interface ITrl {
    [x:number]: string;
}

interface ISome {
    one: string;
    translations: {
        actual: {
            [x:number]: string;
        }
    }
}

const ttt = (a:ITrl) => { ttt2(a) }

const ttt2 = (a:ISome) => { ttt(a) }

const Child: FC<{trls: ITrl}> = ({ trls }) => (
    <div>{trls[1]}{trls.actual[1]}</div>
)

const Parent: FC<{some: ISome}> = ({ some }) => (
    <Child trls={some.translations} />
)

🙁 Actual behavior

We can pass some.translations to Child despite it having not compatible type.

🙂 Expected behavior

Error about types incompatibility

MartinJohns commented 2 years ago

But the types are compatible. Your type ITrl says all number properties must be string, and that's the case (because ISome["translations"] has no number properties). Additional properties are allowed in TypeScript.

You probably want #12936.

brianconnoly commented 2 years ago

But the types are compatible. Your type ITrl says all number properties must be string, and that's the case (because ISome["translations"] has no number properties). Additional properties are allowed in TypeScript.

You probably want #12936.

But why then direct using of such types causes an error?

https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgJIBUoBtkG8CwAUMicgNoAeAXCAK4C2ARtALpXIDOYUoA5gNxEAvkSKhIsRCgzYATHiKlOAe3oQwACz7sCxJaUo0GzKG07c+gvSRHXkyzdB2L9JQ3Sat2XHiAEubYVFCBGUQLmQwKOQAXmQACjgqGSwASliAPjxIqNlE9NsiUPCwHLB5OMTkzCxZdJis3DL85FsgA

RyanCavanaugh commented 2 years ago

Numeric index signatures are a constraint on what types numerically-named keys can have, not a constraint on whether or not non-numeric properties can exist in a type.

brianconnoly commented 2 years ago

Numeric index signatures are a constraint on what types numerically-named keys can have, not a constraint on whether or not non-numeric properties can exist in a type.

@RyanCavanaugh Can you please describe why there is error in my example? It does same thing but interface described directly — nesting is the only difference

fatcerberus commented 2 years ago

For the purposes of assignability, object literal types { ... } are treated as having an implicit index signature. Types defined using interface are not. It has nothing directly to do with the nesting; some.translations has an object literal type while the top-level type ISome is an interface.