Create-React-App uses babel to transpile the TypeScript so it isn't using your npm installed version of TypeScript. Version 3.3.0 of react-scripts supports TypeScript 3.7. You can install it and use it with:

  • yarn add [email protected]

    -or-

  • npm install -s [email protected]

Answer from LukeP on Stack Overflow
🌐
Carl Rippon
carlrippon.com › optional-chaining-with-react-and-typescript
Optional chaining with React and TypeScript
Notice the ? after the subscription and lastPayment properties. This is the optional chaining operator which means if the property before it is null or undefined an error won’t occur if its members are accessed. Instead, the expression will be automatically short-circuited, and undefined returned.
🌐
DEV Community
dev.to › akirautio › optional-chaining-with-react-2l28
Optional chaining with React - DEV Community
December 21, 2020 - Typescript or CRA is luckily not the requirement to use optional chaining when developing with React.
🌐
Reddit
reddit.com › r/typescript › typescript 3.7 beta (optional chaining) with create react app?
r/typescript on Reddit: Typescript 3.7 beta (Optional chaining) with Create React App?
October 5, 2019 -

Hi,

I'm getting the following error using one of the newer features of Typescript 3.7 with Create React App:

Support for the experimental syntax 'optionalChaining' isn't currently enabled

Add @babel/plugin-proposal-optional-chaining (https://git.io/vb4Sk) to the 'plugins' section of your Babel config to enable transformation.

The error only appears on run time; type checking resolves fine on the Intellij Typescript plugin.

And I did add the above plugin to .babelrc.

I'm using:

Create React App @3.2.0,

React@16.10.0,

Typescript@3.7.0-beta,

Optional Chaining Proposal Plugin @7.6.0

What am I missing here?

🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Operators › Optional_chaining
Optional chaining (?.) - JavaScript | MDN
This is an idiomatic pattern in JavaScript, but it gets verbose when the chain is long, and it's not safe. For example, if obj.first is a Falsy value that's not null or undefined, such as 0, it would still short-circuit and make nestedProp become 0, which may not be desirable. With the optional chaining operator (?.), however, you don't have to explicitly test and short-circuit based on the state of obj.first before trying to access obj.first.second:
🌐
Medium
sanjanahumanintech.medium.com › what-is-optional-chaining-in-typescript-7d6430e79917
What is Optional Chaining in TypeScript? | by Sanjana Human In Tech | Medium
October 30, 2023 - Optional Chaining is a feature in TypeScript that allows you to safely access deeply nested properties and methods of an object or array, without explicitly checking for the existence of each level.
Top answer
1 of 2
1

An idea to get rid of optional chaining with you current setup would be to statically type the state of the world and write different components.

Not sure I structured your store correctly but you get the idea.

type RootState = {
    app: 'init' | 'running' // we model the state of the app
    post: {
       Targetfarms: Farmstype | null
    }
}

// We dispatch to the correct implementation depending on the state of the world
const MainPage = () =>
    useSelector({ app }: RootState) => app) === 'running'
        ? RunningPage()
        : InitPage();

const RunningPage = () => {
    const { Targetfarms } = useSelector((state: RunningState) => state.post);

    // OK
    const f = Targetfarms.placeId

}

const InitPage = () => {
    const { Targetfarms } = useSelector((state: InitState) => state.post);

    // @ts-expect-error: Targetfarms is possibly null
    const f = Targetfarms.placeId

}

There are many ways to produce the different states. This is an option.

// When the app is 'running' `post/Targetfarms` is unlocked
type RunningState = Unlock<RootState, ['post', 'Targetfarms']> & {
   state: 'running'
};

// Otherwise Targetfarms is still nullable
type InitState = RootState & {
   state: 'init'
};

type Unlock<State, Path extends PropertyKey[]> = unknown & {
    [K in keyof State]: K extends Path[0]
        ? Path['length'] extends 1
            ? NonNullable<State[K]>
            : Unlock<
                State[K],
                Path extends [PropertyKey, ...infer U] ? U & PropertyKey[] : never
            >
        : State[K]
}

This solution can start to become interesting if you have few app states and lots of nullable pieces of state. Basically you take the decision of what state the app is in once at the root instead of many times where the values are needed.

2 of 2
0

Maybe that you are trying to access a property of an object that may be null or undefined before the initialization. To avoid this error, you have a few options:

You can check if the object is null or undefined before trying to access its properties. For example:

if (Targetfarms) {
  console.log(Targetfarms.placeId);
}

You can set a default value for Targetfarms using the || operator. For example:

const {Targetfarms} = useSelector((state: RootState) => state.post) || {};
console.log(Targetfarms.placeId);

This will set the default value of Targetfarms to an empty object, which means you can access its properties without getting an error.

Note: I think and it's only my opinion here, optional chaining it's a good approach to avoid null or undefined.

🌐
Reddit
reddit.com › r/typescript › how to enforce the use of optional chaining for any type object in typescript?
r/typescript on Reddit: How to enforce the use of optional chaining for any type object in TypeScript?
June 20, 2024 -

I'm trying to enforce the use of optional chaining for accessing properties of any type object in TypeScript to avoid potential runtime errors. For example, I want the following code to throw a TypeScript error:

    catch(e: any) {
        const code = e.code; // This should throw a TypeScript error
    }

But this code should not throw an error:

    catch(e: any) {
        const code = e?.code; // This should not throw a TypeScript error
    }

Is there a way to configure TypeScript to enforce this rule or any workaround to achieve this behavior?

🌐
Medium
medium.com › inside-rimeto › optional-chaining-in-typescript-622c3121f99b
Optional Chaining in TypeScript. Traversing tree-like structures safely… | by Neville Bowers | Inside Rimeto | Medium
December 4, 2019 - This statement is by far the most ... development-time tooling benefits. What’s the catch? TypeScript unfortunately does not yet support an optional chaining operator....
Find elsewhere
🌐
GitHub
github.com › microsoft › TypeScript › issues › 30167
Experimental support of Optional Chaining (at least static property access) via `experimentalOptionalChaining` · Issue #30167 · microsoft/TypeScript
October 6, 2018 - This feature would agree with the rest of TypeScript's Design Goals. If you like the fact that optional chaining was shaken off the dust from #16 and may even be implemented in the near future – send a SWAG from your company to the following address · 050010, Kazakhstan, Almaty, Kabanbay Batyra 21 apt 3, Mobile +7707234004 Pavel Chertorogov ... 👍React with 👍244kix, schickling, venil7, eweilow, nzvtrk and 239 more👎React with 👎17alexander-dobrodiy, Akiyamka, ykirill, strikepark, listochkin and 12 more😄React with 😄1manojvignesh🎉React with 🎉6bmsdave, factormystic, frankr
Published   Mar 01, 2019
🌐
GeeksforGeeks
geeksforgeeks.org › typescript › how-optional-chaining-works-in-typescript
How optional chaining works in TypeScript ? - GeeksforGeeks
March 22, 2022 - TypeScript Optional Chaining is the process of searching and calling variables, methods, parameters that might be nil in existence.
Top answer
1 of 2
28

The problem is you are targeting esnext this will tell the compiler to output all language features as is without any transpilation. Set the language to es2020 (or below) and ?. and ?? will get transpiled to compatible code:

Copy(async function () {
    let imageFileId = (await db.query(sql`select id from image_files where sha256=${sha256}`))[0]?.id;
})()

Playground Link

There is no fine-grained control over which language features get transpiled and which don't do you have to pick a version as a whole unfortunately,

2 of 2
5

Well, I didn't want to use Babel because then I'd have to figure out how to replace ts-node. There's a bunch of outdated docs out there referring to old Babel packages, but these instructions should work as of Nov 2019:

Add a .babelrc file:

Copy{
    "presets": [
        ["@babel/preset-env",{"targets": {"node": "current"}}],
        "@babel/preset-typescript"
    ],
    "plugins": [
        "@babel/plugin-syntax-bigint"
    ]
}

Add these deps:

Copy  "devDependencies": {
    "@babel/cli": "^7.7.0",
    "@babel/core": "^7.7.0",
    "@babel/node": "^7.7.0",
    "@babel/plugin-syntax-bigint": "^7.4.4",
    "@babel/preset-env": "^7.7.1",
    "@babel/preset-typescript": "^7.7.0",
    "@types/node": "^12.7.5",
    "typescript": "^3.7.2"
  }

Execute your code with:

Copynode_modules/.bin/babel-node --extensions ".ts" src/index.ts

The --extensions ".ts" is very important, even though you're explicitly trying to execute a .ts file, it won't transpile it w/out that.

I like to use GNU Make instead of package.json scripts:

CopyMAKEFLAGS += --no-builtin-rules
.SUFFIXES:
NM := node_modules/.bin
.PHONY: build start dev clean test publish

## commands
########################################

__default:
    $(error Please specify a target)

build: build-types build-js dist/package.json

build-types: node_modules/.yarn-integrity
    $(NM)/tsc --emitDeclarationOnly

build-js: node_modules/.yarn-integrity
    $(NM)/babel src --out-dir dist --extensions ".ts" --source-maps inline

run: node_modules/.yarn-integrity
    $(NM)/babel-node --extensions ".ts" src/index.ts

check: node_modules/.yarn-integrity
    $(NM)/tsc --noEmit

dist:
    mkdir -p $@

clean:
    rm -rf node_modules dist yarn-error.log

dist/package.json: package.json | dist
    jq 'del(.private, .devDependencies, .scripts, .eslintConfig, .babel)' $< > $@

## files
########################################

node_modules/.yarn-integrity: yarn.lock
    @yarn install --frozen-lockfile --production=false --check-files
    @touch -mr $@ $<

yarn.lock: package.json
    @yarn check --integrity
    @touch -mr $@ $<

Or just copy from Microsoft's TypeScript Babel Starter.

🌐
CopyProgramming
copyprogramming.com › howto › how-to-enable-optional-chaining-with-create-react-app-and-typescript
Enabling Optional Chaining in TypeScript with Create React App - Typescript
April 8, 2023 - This results in TypeScript recognizing the type as string[] | null . However, when dealing with null values, the expression b?.length returns undefined , leading to an invalid comparison undefined > 1 . To resolve this issue, the condition needs to be rephrased in the following manner: ... Prior to comparing, we ensure that b is not null by verifying the existence of the length property. Optional Chaining Operator in Typescript, I'll just mention here in case you are interested — there are a few utility functions that try to offer a typesafe alternative now, like typesafe-get, optional-chain and (my) get-optional.
Top answer
1 of 3
20

At time of writing, TypeScript does not support the optional chaining operator. See discussion on the TypeScript issue tracker: https://github.com/Microsoft/TypeScript/issues/16

As a warning, the semantics of this operator are still very much in flux, which is why TypeScript hasn't added it yet. Code written today against the Babel plugin may change behavior in the future without warning, leading to difficult bugs. I generally recommend people to not start using syntax whose behavior hasn't been well-defined yet.

2 of 3
12

Update Oct 15, 2019

Support now exists in [email protected]

Say thanks to https://stackoverflow.com/a/58221278/6502003 for the update!


Although TypeScript and the community are in favor of this operator, until TC39 solidifies the current proposal (which at the time of this writing is at stage 1) we will have to use alternatives.

There is one alternative which gets close to optional chaining without sacrificing dev tooling: https://github.com/rimeto/ts-optchain

This article chronicles what the creators were able to achieve in trying to mirror the native chaining operator:

  1. Use a syntax that closely mirrors chained property access
  2. Offer a concise expression of a default value when traversal fails
  3. Enable IDE code-completion tools and compile-time path validation

In practice it looks like this:

import { oc } from 'ts-optchain';

// Each of the following pairs are equivalent in result.
oc(x).a();
x && x.a;

oc(x).b.d('Default');
x && x.b && x.b.d || 'Default';

oc(x).c[100].u.v(1234);
x && x.c && x.c[100] && x.c[100].u && x.c[100].u.v || 1234;

Keep in mind that alternatives like this one will likely be unnecessary once the proposal is adopted by TypeScript.

Also, a big thanks to Ryan Cavanaugh for all the work you are doing in advocating this operator to TC39!

🌐
Reddit
reddit.com › r/typescript › optional chaining
r/typescript on Reddit: Optional chaining
March 6, 2020 -

For some reason I can't use optional chaining in my new project, other TS features like interfaces, types, ... are working fine. Also my IDE is not throwing out any errors, but upon compiling the code, I get this error for the following line of code:

Line of code: country: location?.country

country: location?.country,

SyntaxError: Unexpected token '.'

at Module._compile (internal/modules/cjs/loader.js:895:18)

What's going on?

🌐
Upmostly
upmostly.com › home › tutorials › optional chaining in react
Optional Chaining in React - Upmostly
October 13, 2022 - Our React application is not aware that the server sent a different version of the user object rather than what we were going to be working with. As such, it will try to access the nested properties of type and price which will result in a TypeError being thrown as it does in the screenshot below: ... Luckily for us, in ES6, there was the introduction of the Optional Chaining feature which is a perfect fit for our very scenario.
🌐
Valentino G.
valentinog.com › blog › chaining
Using Optional Chaining in TypeScript and JavaScript
February 7, 2020 - What can we do to protect our code from these kind of errors? Let's see how optional chaining helps. Let's get TypeScript to check our code. Rename optional_chaining.js to optional_chaining.ts.
🌐
TypeScript
typescriptlang.org › docs › handbook › release-notes › typescript-3-7.html
TypeScript: Documentation - TypeScript 3.7
At its core, optional chaining lets us write code where TypeScript can immediately stop running some expressions if we run into a null or undefined. The star of the show in optional chaining is the new ?. operator for optional property accesses.
🌐
GitHub
github.com › kulshekhar › ts-jest › issues › 1283
Syntax Error with Optional Chaining in Typescript 3.7 · Issue #1283 · kulshekhar/ts-jest
November 7, 2019 - "@babel/core": "^7.7.0", "@babel/plugin-proposal-class-properties": "^7.7.0", "@babel/plugin-proposal-decorators": "^7.7.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.4.4", "@babel/plugin-proposal-object-rest-spread": "^7.6.2", "@babel/plugin-proposal-optional-chaining": "^7.6.0", "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/preset-env": "^7.7.1", "@babel/preset-react": "^7.7.0", "@babel/preset-typescript": "^7.7.0", "@types/enzyme": "^3.10.3", "@types/enzyme-adapter-react-16": "^1.0.5", "@types/jest": "^24.0.21", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.15.1", "enzyme-to-json": "^3.4.3", "fork-ts-checker-webpack-plugin": "^3.0.1", "jest": "^24.9.0", "ts-jest": "^24.1.0", "typescript": "^3.7.2", I'm unsure which library is causing the error (ts-jest, jest, babel, etc) but this seemed like a good place to start.
Published   Nov 07, 2019
🌐
LinkedIn
linkedin.com › pulse › mastering-optional-chaining-react-best-practices-safe-apoorve-verma-
Mastering Optional Chaining in React: Best Practices for Safe and Efficient Code
April 11, 2023 - With Optional Chaining, you can write safe, efficient, and maintainable code. To use Optional Chaining, add a question mark (?) before each property you want to access.