Typescript not reading null when returning

Viewed 284

I have a problem with Typescript not reading my return type correctly. I am defining a function with a return type of something | null. And what typescript does is to read only the something type ignoring the null, which can be returned, when I call the function.

function nullornot(): null | string { // here is says it returns null | string
    return null
}

const response = nullornot() // but here is says it returns string

Function declaring

Function call

My tsconfig.json file

{
   "extends": "./tsconfig.paths.json",
   "compilerOptions": {
     "typeRoots": ["node_modules/@types", "src/@types"],
     "allowSyntheticDefaultImports": true,
     "lib": ["ESNext"],
     "moduleResolution": "node",
     "noUnusedLocals": true,
     "noUnusedParameters": true,
     "removeComments": true,
     "sourceMap": true,
     "target": "ESNext",
     "outDir": "lib"
   },
   "files": ["src/@types/graphql.d.ts"],
   "include": ["src/**/*.ts"],
   "exclude": [
     "node_modules/**/*",
     ".serverless/**/*",
     ".webpack/**/*",
     "_warmup/**/*",
     ".vscode/**/*"
   ]
}

My webpack.config.js file

module.exports = {
  context: __dirname,
  mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
  entry: slsw.lib.entries,
  devtool: slsw.lib.webpack.isLocal ? 'eval-cheap-module-source-map' : 'source-map',
  resolve: {
    extensions: ['.mjs', '.json', '.ts'],
    symlinks: false,
    cacheWithContext: false,
    plugins: [
      new TsconfigPathsPlugin({
        configFile: './tsconfig.paths.json',
      }),
    ],
  },
  output: {
    libraryTarget: 'commonjs',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
  },
  optimization: {
    concatenateModules: false,
  },
  target: 'node',
  externals: [nodeExternals()],
  module: {
    rules: [
      // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
      {
        test: /\.(tsx?)$/,
        loader: 'ts-loader',
        exclude: [
          [
            path.resolve(__dirname, 'node_modules'),
            path.resolve(__dirname, '.serverless'),
            path.resolve(__dirname, '.webpack'),
          ],
        ],
        options: {
          transpileOnly: true,
          experimentalWatchApi: true,
        },
      },
      {
        test: /\.graphql?$/,
        use: [
          {
            loader: 'webpack-graphql-loader',
            options: {
              // validate: true,
              // schema: "./src/schema.graphql",
              // removeUnusedFragments: true
              // etc. See "Loader Options" below
            }
          }
        ]
      }
    ],
  },
  plugins: [],
};

Thanks for all help!

2 Answers

To type the result as string | null, you need to enable strictNullChecks in compilerOptions like this:

"compilerOptions": {
  "strictNullChecks": true
}

See the TypeScript docs for more details.

It's because you don't have the strictNullChecks flag set to true in the tsconfig. Therefore TS won't enforce null checks, so for all intents and purposes it's just a string.

See how in this playground link where strict null checks are off it behaves the same as you're seeing, but once you turn it on the type of response is string | null

If this is a new project I'd recommend activating the strictest settings for the best type safety.

Related