Skip to content

When creating a mapped type of an indexed type it extends too liberal #32484

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jauco opened this issue Jul 19, 2019 · 1 comment · Fixed by #35143
Closed

When creating a mapped type of an indexed type it extends too liberal #32484

jauco opened this issue Jul 19, 2019 · 1 comment · Fixed by #35143
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue

Comments

@jauco
Copy link

jauco commented Jul 19, 2019

TypeScript Version: 3.6.0-dev.20190719

Search Terms:
Mapped types extends Index types

Code

type constr<Source, Tgt> = {[K in keyof Source]: string } &Pick<Tgt, Exclude<keyof Tgt, keyof Source>> 


type s = constr<{}, {
  [key: string]: {
      a: string;
  };
}>
declare const q: s
q["asd"].a.substr(1) //see: a is a string
q["asd"].b  //and of course b does not exist (this line will have an error)

//but I expect the following line to error as well
const d: {[key: string]: {a: string, b: string}} = q
//and verify to be "no" (instead it is "yes")
type verify = s extends {[key: string]: {a: string, b: string}} ? "yes" : "no"

// the error _is_ shown if you construct a (seemingly identical) type by hand
type sManual =  {} & Pick<{
    [key: string]: {
        a: string;
    };
}, string | number>
declare const qManual: sManual
// see: error here
const dManual: {[key: string]: {a: string, b: string}} = qManual

//the error is also shown if I replace the indexed type with an actual property
type s2 = constr<{}, {
  asd: {
      a: string;
  };
}>
declare const q2: s2
q2.asd.a.substr(1) //this is the same
q2.asd.b //this also


//But this is now an error (as it should be)
const d2: {asd: {a: string, b: string}} = q2

//and this is "no" (as it should be)
type verify2 = s2 extends {asd: {a: string, b: string}} ? "yes" : "no"

Expected behavior:
As described inline. I do not think q should be assignable to d
Actual behavior:
q is assignable to d

Playground Link: http://www.typescriptlang.org/play/#code/C4TwDgpgBAxg9gOwM7AE4B4DKcCuqYQA0UAKgObAB8UAvFAN4DaA0lAJYJQDWEIcAZlGx4CAXQBcUFKg5koAXygAyAApsYXdOWDEAogA8YAGxwATCOh59B24lYFDc+CJWoAoD6EhTasRNPR6eWJ6NygoRitJaVkJBjDwxIBDaLRZAG4E+Uz5SjdzYyTUaHhkYCgAR2i3CsYAIiSkUzrRADok1qQcACNpAAoARgBKKAB6UaQICEkk9iQoWZiEMhr6xua27vDxpIRTKAd4PEmoLdM4CHmEOHKIfTYUKD7gAAsHqCMOaAB3NiMjKAvJIAN2guygEFQqDgqCGHnG3Rw5QAkhD9JAYOVXtB+HB-nBfssPl8oMA4BCoTCFvNvhB-m5So9TJImFEpGllnF6Cl2TJlsRuqk+WR5Io6BU3Ds9lBQTJ+CBSeTutA6tc6k8OCgIEl9mxyu86iBLnU4V5oLK2PLfPM7sAIHt5qzeELYiyeUsyAKXctRVAAPxQQ3GqCSVVwOrw0akl7QSHQ1BQAD6D0T0eh304lqgfBwfjKqBwmIWT0mEAAtrIjAq2OYEMB1EkjCMzacFUC9m4W0gALK7HCN3wMRRKKBqDSBBLhSLO3mu+KJBcLb1kTIL7JuYKzokAHygCBwZeVqDyBSMRRK-nKFV7+8b0Rv-aMkqjpckcapMeKDMvUFMD7vDDTiAy5cu6HKeqcy6+uK-5Ps+yKCKixRgGeBDRtAHDmPoED7C2vyvAsnBJJij5QGA0KQKgoCduA0BIAATL4jJoIEm6hOE6wspOyTLquCg5CeECFMUeaPBU9HRPRNT0e0TTtJ0PT9MMYyjK87zvNiUhJGWEDSbJpitFs4xqfMjZIHAHjPgAQki0bqVcBKERS8ZPI07DlEgLy4EY+zKnCzG-hJDCccFy5eluIpipUUnPrsuFvPMBpqq5iUeV5OA+acECmrRMqQpaICMXQDFonaDrBU0bphZBEW+gGQZIOqoZqm4QA

Related Issues: Sorry, no. But as evidenced by my search terms I have some trouble finding the right words to describe the bug

@ahejlsberg
Copy link
Member

Simple repro:

declare let s: { a: string } & { b: number };
declare let t: { [key: string]: string };
t = s;  // No error!

Surprisingly we don't error on the above, but we definitely should. Specifically, when relating an intersection type to a type with an index signature, we need to check that all constituents in the intersection type are related to the index signature. We currently only check that some constituent is related.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue
Projects
None yet
3 participants