microsoft / TypeScript

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

Wrong error : Object is possibly 'undefined'. (TS2532) #41542

Closed hckhanh closed 3 years ago

hckhanh commented 3 years ago

TypeScript Version: v4.2.0-dev.20201112

Search Terms: TS2532, undefined

Code

export default function App() {
  const { data, error } = useSWR<object, Error>(
    "https://jsonblob.com/api/jsonBlob/01861067-2595-11eb-bacf-717e52210c0a"
  );

  if (!data && !error) {
    return <div>Loading...</div>;
  } else if (error) {
    return <div>Error: {error.message}</div>;
  }

  return <div>{data.array}</div>;
}

Expected behavior: There is no way data can be undefined when it's rendered

Actual behavior: Object is possibly 'undefined'. (TS2532) appears at data.array

Playground Link: https://codesandbox.io/s/object-is-possibly-undefined-ts2532-n3kxp

Related Issues: I already searched but no result for me.

RyanCavanaugh commented 3 years ago

We don't have any mechanisms in place that can account for the complementarity of x and !x and don't plan to add any. There's no reason not to write this code more straightforwardly:

if (data) {
  return data.array;
}
if (error) {
  return "error";
}
return "loading";
nhhockeyplayer commented 3 years ago

have you attempted your band-aid work around on a live THIS object?

this-issue is terrible

its wiped out my pre handler hook I cannot even reference THIS on any of these lines and its blocking all attempts to augment any reference to THIS fail

@pre<Question>('save', (next) => {
    if (this.createdAt !== null) {
        this.createdAt = this.updatedAt = new Date()
    }
    this.updatedAt = new Date()
    next()
})
export class Question extends Typegoose implements IQuestion {

I have a previous released project using a lesser version of typescript 4.0.5 that works fine with above code

im on the typescript 4.1.3 and the above code refuses to work

I dont want to sound offensive typescript has held its own...awesome work... but this is feeling like a nasty regression

I have set all meta flags in tsconfig as appropriate

      "strict": false,
      "strictFunctionTypes": false,
      "noStrictGenericChecks": false,
      "sourceMap": true,
      "declaration": false,
      "module": "ESNext",
      "moduleResolution": "node",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true
RyanCavanaugh commented 3 years ago

@nhhockeyplayer can you please log a new issue with a complete repro? This doesn't look related to the problem described in the OP

nhhockeyplayer commented 3 years ago

Ok I will check my fire

I backed down to 4.0.5 and its happening on both

I have alot of code spread out across several projects

dont be alarmed if its legit you will hear more from me

Im still in shakedown mode

icecream17 commented 3 years ago

I understand that there's no way to detect what the code does, but how can I change this code to make ts not throw this error?

interface exampleType {
   property?: [number]
}

function example(someObject: exampleType) {
   if (!('property' in someObject)) someObject.property = [0]
   return someObject.property[0] // Error: Object is possibly undefined
}

example({})

https://codesandbox.io/s/error-ts2532-object-is-possibly-undefined-3c3lo?file=/src/index.ts

Edit: fixed https://www.typescriptlang.org/play?target=8#code/JYOwLgpgTgZghgYwgAggDzgWwA4BsIAqAntigN4BQy12UA9qVGEQPwBcyA2iAK6YBG0ALoUAvhQoweIBGGB0QqDDnwAKAM51MEAPL8AVhFkd0WPIRIQAlMkrVkm7XsOyAdLQbRmyFiwC8XAAMIvZQEGA8UIqOugZGYO70jMycwcgA9OnIAKJQ9FAczvHIwOrI2HTq6sD8uETI0gAmEDCgEI1iEqYqEKpkolZAA

interface exampleType {
   property?: [number]
}

function example(someObject: exampleType) {
   someObject.property ??= [0]
   return someObject.property[0]
}

example({})
nhhockeyplayer commented 2 years ago

this remains an issue

TS2532: Object is possibly 'undefined'.

@pre<RoleEntity>('save', (next) => {
    if (!this.createdAt) {
        this.createdAt = this.updatedAt = new Date()
    }
    this.updatedAt = new Date()
    next()
})
export class ...

unable to operate THIS pointer

nhhockeyplayer commented 2 years ago

its not very encouraging to close something that was not even vetted to be closed

does integrity exist in this world?

why would someone do this?

just to close it and make it gone? Does that do truth anything? ??

icecream17 commented 2 years ago

Maybe try:

    this.createdAt ??= this.updatedAt = new Date()
zz-james commented 2 years ago

I think the problem is that arrow functions don't have a 'this' try using an old school function definition?

this remains an issue

TS2532: Object is possibly 'undefined'.

@pre<RoleEntity>('save', (next) => {
    if (!this.createdAt) {
        this.createdAt = this.updatedAt = new Date()
    }
    this.updatedAt = new Date()
    next()
})
export class ...

unable to operate THIS pointer

schoettler commented 2 years ago

image

@RyanCavanaugh