Skip to content

Object is possibly 'undefined' #29642

Closed
Closed

Description

@troy351

TypeScript Version: 3.4.0-dev.201xxxxx

Search Terms: Object undefined

Code turn strictNullChecks on

// A *self-contained* demonstration of the problem follows...
// Test this by running `tsc` on the command-line, rather than through another build tool such as Gulp, Webpack, etc.
type EventType = 'click' | 'dblclick'

const handlerMap: { [P in EventType]?: any[] } = {}

function addHandler<P extends EventType>(evType: P) {
  const handlerList = handlerMap[evType] || []
  handlerList.push({}) // Error here: Object is possibly 'undefined'
  handlerMap[evType] = handlerList
}

Expected behavior: No Error

Actual behavior: Shows Error

Playground Link: http://www.typescriptlang.org/play/#src=type%20EventType%20%3D%20'click'%20%7C%20'dblclick'%0Aconst%20handlerMap%3A%20%7B%20%5BP%20in%20EventType%5D%3F%3A%20any%5B%5D%20%7D%20%3D%20%7B%7D%0Afunction%20addHandler%3CP%20extends%20EventType%3E(evType%3A%20P)%20%7B%0A%20%20const%20handlerList%20%3D%20handlerMap%5BevType%5D%20%7C%7C%20%5B%5D%0A%20%20handlerList.push(%7B%7D)%20%2F%2F%20Error%20here%3A%20Object%20is%20possibly%20'undefined'%0A%7D%0A

Related Issues:

Activity

  1. collin5 commented on Feb 1, 2019

    @collin5
    Contributor

    Will be giving this a try.

  2. ktoto commented on Feb 18, 2019

    @ktoto

    It's the same issue?

    interface State {
        [i: string]: {data?: {id:string}} | undefined
     }
    
    declare var x: State;
    
    const id = 'xx';
    const y = x[id] && x[id].data; // Error: Object is possibly 'undefined' (with strictNullChecks
    const yId = y && y.id; // correct type – string | undefined

    Playground link : https://www.typescriptlang.org/play/#src=interface%20State%20%7B%0D%0A%20%20%20%20%5Bi%3A%20string%5D%3A%20%7Bdata%3F%3A%20%7Bid%3Astring%7D%7D%20%7C%20undefined%0D%0A%20%7D%0D%0A%0D%0Adeclare%20var%20x%3A%20State%3B%0D%0A%0D%0Aconst%20id%20%3D%20'xx'%3B%0D%0A%0D%0Aconst%20y%20%3D%20x%5Bid%5D%20%26%26%20x%5Bid%5D.data%3B%0D%0A%0D%0Aconst%20yId%20%3D%20y%20%26%26%20y.id%3B%0D%0A

  3. weswigham commented on Mar 14, 2019

    @weswigham
    Member

    #29317 should be the fix here (which I have mentioned in Collins Abitekaniza (@collin5) 's PR). Specifically, the type of a || b should be calculated as (typeof a & not FalseyTypes) | typeof b, where FalseyTypes is 0 | false | "" | undefined | null.

    Ryan Cavanaugh (@RyanCavanaugh) given that, should we move this out of 3.4, since we won't be shipping them in 3.4?

  4. weswigham commented on Mar 14, 2019

    @weswigham
    Member

    Stanislav Svirid (@ktoto) your issue is different - since State has an index signature, we don't track refinements on individual property lookups within it - see #17960 and #29042 (and go updoot those issues so they don't sit in the backlog).

  5. MufidJamaluddin commented on May 10, 2019

    @MufidJamaluddin

    I have same issue. :(

    Typescript Version : 3.4.5

    undefined

  6. troy351 commented on May 10, 2019

    @troy351
    Author

    Mufid Jamaluddin (@MufidJamaluddin) duplicate of #7719

    Workaround is use kelas!.iskelas

  7. micky2be commented on Jun 13, 2019

    @micky2be

    Same issue as Mufid Jamaluddin (@MufidJamaluddin)
    I have a checker in place to avoid duplicating code but Typescript ignores it and output this error.

  8. 27 remaining items

  9. RyanCavanaugh commented on Jan 23, 2020

    @RyanCavanaugh
    Member

    Tracking at #7719

  10. typescript-bot commented on Jan 26, 2020

    @typescript-bot
    Contributor

    This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

  11. andreialecu commented on May 15, 2020

    @andreialecu

    Ryan Cavanaugh (@RyanCavanaugh) did you link the wrong issue? That one has been closed since 2018.

  12. ecklf commented on May 15, 2020

    @ecklf

    Also having this issue

    Code

    type Key = "key1" | "key2";
    type Keys = {
      [P in Key]?: { keyProp: string };
    };
    
    const keys: Keys = {
      key1: { keyProp: "keyPropVal" },
    };
    
    let someKey!: Key;
    
    if (keys[someKey]) {
      // This shows Object is possibly 'undefined'
      keys[someKey].keyProp;
    }
    Output
    "use strict";
    const keys = {
        key1: { keyProp: "keyPropVal" },
    };
    let someKey;
    if (keys[someKey]) {
        // This shows Object is possibly 'undefined'
        keys[someKey].keyProp;
    }
    Compiler Options
    {
      "compilerOptions": {
        "noImplicitAny": true,
        "strictNullChecks": true,
        "strictFunctionTypes": true,
        "strictPropertyInitialization": true,
        "strictBindCallApply": true,
        "noImplicitThis": true,
        "noImplicitReturns": true,
        "useDefineForClassFields": false,
        "alwaysStrict": true,
        "allowUnreachableCode": false,
        "allowUnusedLabels": false,
        "downlevelIteration": false,
        "noEmitHelpers": false,
        "noLib": false,
        "noStrictGenericChecks": false,
        "noUnusedLocals": false,
        "noUnusedParameters": false,
        "esModuleInterop": true,
        "preserveConstEnums": false,
        "removeComments": false,
        "skipLibCheck": false,
        "checkJs": false,
        "allowJs": false,
        "declaration": true,
        "experimentalDecorators": false,
        "emitDecoratorMetadata": false,
        "target": "ES2017",
        "module": "ESNext"
      }
    }

    Playground Link: Provided

  13. Casa-Cloud commented on May 16, 2020

    @Casa-Cloud

    Hello All,

    The object is possibly 'undefined',

    This warning is shown by the editor when we provide the body definition of some variable in the form of the interface and add some of the fields as optional

    Eg:-

    interface Blog {
      autherName: string;
      contents?: any[],
      id: string
    }
    
    

    While using this interface Blog in our code if we are trying to do some loop on Blog.contents
    Eg:-

    const newBlog: Blog = JSON.parse(blog);
    for (const content of newBlog.contents) {`
       console.log("content ", content );
    }
    
    

    This will error in for loop declaration for (const content of newBlog.contents) because we have said in an interface that contents property in Blob object can be or cannot be there hence we first need to check in code if the property is present then we should use it. As follows

    Eg:-

    if (newBlog.contents && newBlog.contents.length > 0) {
        for (const content of newBlog.contents) {
          console.log("content ", content );
       }
    }
    

    This is one way to resolve this warning.

    Happy Coding!

  14. harishkshetty commented on May 17, 2020

    @harishkshetty

    Hello All,

    The object is possibly 'undefined',

    This warning is shown by the editor when we provide the body definition of some variable in the form of the interface and add some of the fields as optional

    Eg:-

    interface Blog {
      autherName: string;
      contents?: any[],
      id: string
    }
    

    While using this interface Blog in our code if we are trying to do some loop on Blog.contents
    Eg:-

    const newBlog: Blog = JSON.parse(blog);
    for (const content of newBlog.contents) {`
       console.log("content ", content );
    }
    

    This will error in for loop declaration for (const content of newBlog.contents) because we have said in an interface that contents property in Blob object can be or cannot be there hence we first need to check in code if the property is present then we should use it. As follows

    Eg:-

    if (newBlog.contents && newBlog.contents.length > 0) {
        for (const content of newBlog.contents) {
          console.log("content ", content );
       }
    }
    

    This is one way to resolve this warning.

    Happy Coding!

    Thanks alokadhao20,It solved issue for me.

  15. subins2000 commented on Jul 4, 2020

    @subins2000

    Ryan Cavanaugh (@RyanCavanaugh) did you link the wrong issue ? That one has been closed since 2018.

  16. locked as off topic and limited conversation to collaborators on Jul 8, 2020
  17. RyanCavanaugh commented on Jul 8, 2020

    @RyanCavanaugh
    Member

    Locking because everyone is posting about all of their "is possibly undefined" code snippets here without context for the original post.

    The inability to handle x || [] when x is a type parameter is a current design limitation wherein we need to have some new mechanism for describing higher-order facts about generic type parameters; today if something is T and we know it's truthy or falsy, there's no mechanism for us to better describe its assignability to any given target type. Everything we've tried so far here has been a performance or usability disaster so it's on the back burner for the time being until we can hopefully have some better insight on how to represent this in a more ergonomic/efficient way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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