TS 3.4: Error when passing dynamically imported generic type as a function argument
See original GitHub issueTypeScript Version: 3.4.0-dev.201xxxxx
Search Terms: TS2322, dynamic import, dynamic import never, dynamic import generic
Code
.\node_modules\.bin\tsc --jsx react --lib es2017 --strict index.tsx
// ===== page.tsx ======
import * as React from 'react'
export interface PageProps {
title: string
}
export class Page extends React.Component<PageProps> {
render() {
return <div>{this.props.title}</div>
}
}
// ===== index.tsx =====
import * as React from 'react'
import{ PageProps, Page } from './page'
export function myFunction<TProps>(loader: () => Promise<React.ComponentType<TProps>>) {
}
// No error
myFunction(() => Promise.resolve(Page))
// No error
const loader: () => Promise<React.ComponentType<PageProps>> = () => import('./page').then(m => m.Page)
// Error
myFunction(() => import('./page').then(m => m.Page))
Expected behavior:
No compile error. This was the behavior in TS 3.3 and earlier.
Actual behavior:
There is an error after upgrading to TS 3.4:
index.tsx:14:18 - error TS2322: Type 'Promise<typeof Page | ComponentClass<never, any> | FunctionComponen
t<never>>' is not assignable to type 'Promise<ComponentType<PageProps>>'.
Type 'typeof Page | ComponentClass<never, any> | FunctionComponent<never>' is not assignable to type 'C
omponentType<PageProps>'.
Type 'ComponentClass<never, any>' is not assignable to type 'ComponentType<PageProps>'.
Type 'ComponentClass<never, any>' is not assignable to type 'ComponentClass<PageProps, any>'.
Type 'PageProps' is not assignable to type 'never'.
14 myFunction(() => import('./page').then(m => m.Page))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index.tsx:4:44
4 export function myFunction<TProps>(loader: () => Promise<React.ComponentType<TProps>>) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The expected type comes from the return type of this signature.
Repro here: https://github.com/srmagura/ts-import-repro
Issue Analytics
- State:
- Created 4 years ago
- Reactions:10
- Comments:16 (12 by maintainers)
Top Results From Across the Web
Is there a way I can import types using a generic parameter?
It is not possible, at least as of TypeScript 4.6, to express " import types" of a form like import(T) or typeof import(T)...
Read more >Documentation - Conditional Types - TypeScript
But the power of conditional types comes from using them with generics. For example, let's take the following createLabel function: ts. interface IdLabel...
Read more >The Ceylon Language
Since generic type arguments are reified at runtime, the metamodel fully captures generic types at both compile time and execution time. Attribute<String,ย ...
Read more >More types - mypy 0.991 documentation
This section introduces a few additional kinds of types, including NoReturn , NewType , TypedDict , and types for async code. It also...
Read more >Overview - TypeScript
During type argument inference in TypeScript 3.4, for a call to a generic function that returns a function type, TypeScript will, as appropriate,...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@sandersn those workarounds canโt be used by library writers but have to be known by the consumers of the libraryโฆ
it is affecting a large number of people - e.g. everyone who is using nextjs with dynamic imports: https://nextjs.org/docs/advanced-features/dynamic-import
could you please consider picking up this issue once again?
@styu
Workarounds:
avoid context by extracting
import('./page').then(m => m.Page)
:This avoids the return type inference since there is no contextual type to infer from.
provide a real or fake
onrejected
:This one is fake โ
null as never
disappears nicely in the type system โ but a real app should probably provide a fallback page in case the import fails.