-
Notifications
You must be signed in to change notification settings - Fork 12.8k
TSC returns an error for TSX code where the plain TS equivalent compiles fine #14036
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
Comments
Probably worth raising here : https://github.com/facebook/jsx/issues/new for some explicit syntax in JSX 🌹 |
@basarat I'm not sure what you are suggesting; it has nothing to do with the original JSX syntax IMHO. |
I understand 🌹 |
+1 for this or at least #6395 |
+1 Yes please, type inference would be IMHO the correct (and welcomed) solution. |
It would be great if TypeScript at least could infer generics even though you can't write them explicitly.
a fails with
but b have no issues. |
There is not really a place for inference to happen here. there is no reason to assume that the The best option here is #6395, where you can explicitly specify your type arguments. |
@mhegazy Maybe "type inference" is the wrong terminology. Nevertheless, since the Basically, since we do have the JSX mode and the JSX factory settings, the compiler should IMHO generate the same AST in both cases, and whenever the React typings are available also react (no pun intended) the same - no hardcoding needed. |
There is no inference happening in the second one either ( |
@mhegazy OK, even if type SelectProps<T> = { items: T[] }
class Select<T> extends React.Component<SelectProps<T>, any> { }
const someItems = [1, 2, 3, 4];
function renderJsOk() {
return React.createElement(Select, { items: someItems }); // No error
}
function renderJsFail() {
return React.createElement(Select, { itemz: someItems }); // Error
} The question I'm asking really is this: why does the plain and the JSX version not behave the same, e.g. why is there a compile error in the JSX case? If the JSX case was acting the same as the plain version I'd be pretty happy already, as it would allow people to use JSX syntax throughout and achieve the same level of type safety as with the plain version, e.g. checking that the passed in properties are valid (even if it is using Note that this is only equivalent to making the component non-generic on the call site. Being generic makes sure that the code of the component itself will not be littered with |
with #15455, you can get the same bahvuour with default paramters: import * as React from "react";
type SelectProps<T > = { items: T[] }
class Select<T = any> extends React.Component<SelectProps<T>, any> { }
const someItems = [1, 2, 3, 4];
const someItems2 = ["ss"];
function renderJsx() {
return <Select items={someItems} />; // OK
} |
@mhegazy Thank you for the hint, I'll use that when it becomes available in the stable version. Nevertheless it remains unclear to me why the plain and the JSX-style code do not behave the same, could you maybe shed some light on that? |
@avonwyss The reason is on how we resolve JSX.Expression. The way we resolve React.Component in JSX-style syntax is different than how we do for normal function in particular it doesn't go through overload resolution logic (like how new call expression does). In 2.3, however, stateless-function component does go through overload resolution and so if you declare function Select<T>(attr: SelectProps<T>) {...} We are considering using overload resolution when we are trying to resolve JSX expression that is declared as React Component class. |
Thank you @yuit for explaining the difference. Indeed, I think that using the same overload resolution would be the correct way to do things, so that behavior remains consistent (even more so in the light of using other JSX factories). |
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed. |
TypeScript Version: 2.1.5
Code
Expected behavior:
TS should infer the generic type in the
renderJsx
function just as it does in therenderJs
function.Actual behavior:
TS requires a generic type argument which unfortunately cannot be specified because this is not supported by the parser.
See also #3960 for some related discussions.
The text was updated successfully, but these errors were encountered: