Skip to content

[3.5.1] Type 'NonNullable<Partial<Config>[T]>' is not assignable to type 'Config[T]' #31675

Closed
@kryops

Description

@kryops

TypeScript Version: 3.5.1, 3.6.0-dev.20190530

Search Terms:

partial nonnullable generic mapped strictNullChecks

Code

interface Config {
  string: string
  // There need to be different types in here for the error to occur
  number: number
}

function getConfigOrDefault<T extends keyof Config>(
  userConfig: Partial<Config>,
  key: T,
  defaultValue: Config[T]
): Config[T] {
  const userValue = userConfig[key] // Partial<Config>[T]
  const explicitAssertion = userConfig[key] as Config[T] | undefined // allowed

  // Partial<Config>[T] - already incorrect in 3.4.5?
  const simpleCheck = userValue ? userValue : defaultValue

  // 3.4.5: Config[T]
  // 3.5.1, 3.6.0-dev.20190530: Config[T] | NonNullable<Partial<Config>[T]>
  const assertedCheck = userValue ? userValue! : defaultValue

  return assertedCheck
}

Expected behavior:

No error

Actual behavior:

Type 'Config[T] | NonNullable<Partial<Config>[T]>' is not assignable to type 'Config[T]'.
  Type 'NonNullable<Partial<Config>[T]>' is not assignable to type 'Config[T]'.
    Type 'Partial<Config>[T]' is not assignable to type 'Config[T]'.
      Type 'Partial<Config>' is not assignable to type 'Config'.
        Types of property 'string' are incompatible.
          Type 'string | undefined' is not assignable to type 'string'.
            Type 'undefined' is not assignable to type 'string'.
              Type 'Partial<Config>[T]' is not assignable to type 'string & number'.
                Type 'Partial<Config>[T]' is not assignable to type 'string'.
                  Type 'string | number' is not assignable to type 'Config[T]'.
                    Type 'string' is not assignable to type 'Config[T]'.
                      Type 'string' is not assignable to type 'string & number'.
                        Type 'string' is not assignable to type 'number'.
                          Type 'NonNullable<Partial<Config>[T]>' is not assignable to type 'string & number'.
                            Type 'Partial<Config>[T]' is not assignable to type 'string & number'.
                              Type 'string | number | undefined' is not assignable to type 'string & number'.
                                Type 'undefined' is not assignable to type 'string & number'.
                                  Type 'undefined' is not assignable to type 'string'.
                                    Type 'Partial<Config>[T]' is not assignable to type 'string'.
                                      Type 'string | number' is not assignable to type 'string & number'.
                                        Type 'string' is not assignable to type 'string & number'.
                                          Type 'string' is not assignable to type 'number'.
                                            Type 'NonNullable<Partial<Config>[T]>' is not assignable to type 'string'.
                                              Type 'Partial<Config>[T]' is not assignable to type 'string'.
                                                Type 'string | number | undefined' is not assignable to type 'string'.
                                                  Type 'undefined' is not assignable to type 'string'.
                                                    Type 'string | number' is not assignable to type 'string'.
                                                      Type 'number' is not assignable to type 'string'.ts(2322)

with strictNullChecks: true

Playground Link:

https://www.typescriptlang.org/play/index.html#src=interface%20Config%20%7B%0D%0A%20%20string%3A%20string%0D%0A%20%20%2F%2F%20There%20need%20to%20be%20different%20types%20in%20here%20for%20the%20error%20to%20occur%0D%0A%20%20number%3A%20number%0D%0A%7D%0D%0A%0D%0Afunction%20getConfigOrDefault%3CT%20extends%20keyof%20Config%3E(%0D%0A%20%20userConfig%3A%20Partial%3CConfig%3E%2C%0D%0A%20%20key%3A%20T%2C%0D%0A%20%20defaultValue%3A%20Config%5BT%5D%0D%0A)%3A%20Config%5BT%5D%20%7B%0D%0A%20%20const%20userValue%20%3D%20userConfig%5Bkey%5D%20%2F%2F%20Partial%3CConfig%3E%5BT%5D%0D%0A%20%20const%20explicitAssertion%20%3D%20userConfig%5Bkey%5D%20as%20Config%5BT%5D%20%7C%20undefined%0D%0A%0D%0A%20%20%2F%2F%20Partial%3CConfig%3E%5BT%5D%20-%20already%20incorrect%20in%203.4.5%3F%0D%0A%20%20const%20simpleCheck%20%3D%20userValue%20%3F%20userValue%20%3A%20defaultValue%0D%0A%0D%0A%20%20%2F%2F%203.4.5%3A%20Config%5BT%5D%0D%0A%20%20%2F%2F%203.5.1%2C%203.6.0-dev.20190530%3A%20Config%5BT%5D%20%7C%20NonNullable%3CPartial%3CConfig%3E%5BT%5D%3E%0D%0A%20%20const%20assertedCheck%20%3D%20userValue%20%3F%20userValue!%20%3A%20defaultValue%0D%0A%0D%0A%20%20return%20assertedCheck%0D%0A%7D%0D%0A

(error does not occur there - which TS version does the playground run on?)

Related Issues:

These issues looked similar but were already reported for earlier versions of TypeScript:

#27456
#30706

Metadata

Metadata

Assignees

Labels

Fix AvailableA PR has been opened for this issueNeeds InvestigationThis issue needs a team member to investigate its status.RescheduledThis issue was previously scheduled to an earlier milestone

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions