-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Object is possibly 'undefined' #29642
Comments
Will be giving this a try. |
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 |
#29317 should be the fix here (which I have mentioned in @collin5 's PR). Specifically, the type of @RyanCavanaugh given that, should we move this out of |
@MufidJamaluddin duplicate of #7719 Workaround is use |
Same issue as @MufidJamaluddin |
@marcj Same error, but as with @ktoto's, the issue has more to do with #29042 and #17960. Ultimately, the question is how much TypeScript can be asked to simulate when checking keys. 3.5.3 seems to handle checking of a constant string index whose value was set with a constant string index after initialization, and of a constant variable index whose value was defined on declaration, but not a variable index for a value assigned after initialization. const myObj: { prop?: number } = {};
myObj['prop'] = 1;
if (myObj['prop']) {
myObj['prop'] = 1 * myObj['prop']; // No error
}
const field = 'prop'
if (myObj[field]) {
myObj[field] = 1 * myObj[field]; // Possibly undefined
}
const otherObj = {prop: 1};
if (otherObj[field]) {
otherObj[field] = 1 * otherObj[field]; // No error
} Your case stands out because it requires dynamic assignment, dynamic retrieval, and continued access to the original object. Casting workaround that could get tedious: interface KeyType {setValue: (input: string) => void};
const myObj: { aa?: KeyType} = {};
const key = 'aa';
myObj[key] = {setValue: (input): void => {console.log(input);}}
if (myObj[key]) {
(myObj[key] as KeyType).setValue('bb');
} |
|
Another example without dynamic property access: import React from "react";
interface IPropsPrivate<T> {
someField: T;
maybeRows?: string[];
}
type IProps<T> = T extends string ? never : IPropsPrivate<T>;
class Class1<T> extends React.PureComponent<IProps<T>> {
public render() {
const maybeRows = this.props.maybeRows;
const notUndefined = maybeRows === undefined ? [] : maybeRows;
notUndefined.filter(() => true); // Error: Object is possibly 'undefined'.
const twiceGuaranteedUndefined = notUndefined || [];
twiceGuaranteedUndefined.filter(() => true); // Error: Object is possibly 'undefined'.
return null;
}
}
// This works fine though
class Class2<T> extends React.PureComponent<IProps<T>> {
public render() {
const { maybeRows = [] } = this.props;
maybeRows.filter(() => true);
return null;
}
} |
Another example, tried on type DialogProps = {
buttons?: {
primary: boolean;
secondary?: boolean;
};
};
function Dialog({ buttons }: DialogProps) {
const atLeastOneButton = buttons !== undefined;
if (atLeastOneButton) {
const label = buttons.primary;
// throws "Object is possibly 'undefined' over `buttons`
}
} Apparently, the compiler doesn't understand that |
There is a problem with a new version of TypeScript that hasn't been occuring before. It's related to Diagnostics being enabled and reporting on some [practically non-existing issues][1], such as: > Object is possibly 'undefined' This could be avoided by adding the `!` symbol to the object which tricks the `tsc` to trust the developer. I see that as a scary practice, which could quickly turn into something like `font-size: 10px !important;`... Instead, we're telling `jest`, not to run these diagnostics itself, as personally I trust that linter and `tsc` itself will be able to handle it and these don't throw these errors. Saying that, it makes me think there is some other configuration to jest, that could allow us keep the diagnostics, as well as act the same way the linter/tsc do. Disabling it for now, seems like sane approach. [1]: microsoft/TypeScript#29642
@rasmus-storjohann-PG gunna need some more information on the shapes of the types in question to get an actual repro of that - I'd also open a new issue, since it looks like a pretty distinct bug (just resulting in the same diagnostic message). |
Another example below in case it helps. |
why is this not allowed?
|
Because it does not make sense (in a strongly typed language) to supply a non-numerical value to an operation meant to compare two numbers. JavaScript's answer (always false if either argument cannot be converted into a number) is arbitrary. This is correct behavior unrelated to this issue. |
@MBerka I disagree. I specifically typed the argument. I know it can be undefined. I am not accessing any object properties/methods. The comparison is valid JS why am I prevented from running? |
@gkamperis That's valid JS but bad part of JS which TS whats to get rid of. |
@troy351 This check is about NPEs only. There is no chance an NPE can happen here. So the message is not valid. |
@gkamperis Yeah, for the complier, TS was made for JS users to make less mistakes and that's how TS did it. Consider this one checkIsPositive(num: number | undefined): boolean {
return !(num <= 0)
} |
Tracking at #7719 |
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
@RyanCavanaugh did you link the wrong issue? That one has been closed since 2018. |
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 |
Hello All,
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:-
While using this interface Blog in our code if we are trying to do some loop on Blog.contents
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:-
This is one way to resolve this warning. Happy Coding! |
Thanks alokadhao20,It solved issue for me. |
@RyanCavanaugh did you link the wrong issue ? That one has been closed since 2018. |
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 |
TypeScript Version: 3.4.0-dev.201xxxxx
Search Terms: Object undefined
Code turn
strictNullChecks
onExpected 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:
The text was updated successfully, but these errors were encountered: