-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
JSX: a way to make all the properties of value-based elements optional #7004
Comments
So what is the proposal? |
I think we could reasonably say that private / protected members get ignored when checking against the element attributes type. |
Probably something like declare namespace JSX { interface ElementOptionalAttributesProperty {} } All the properties would be considered optional. Not ideal but could be a good start. Ideally, I'd like to use decorators to mark required properties, like |
Discussed at the backlog slog today. There are a lot of scenarios here that would be helped by this, but the technical implications of the first type operator are very large. Some more notes are at #8228. We're continuing to think about it. Just in terms of setting expectations, this isn't going to be something we can do in time for TypeScript 2.0 |
I opened duplicated issue #12016 . I read backlog slog. I think I do not want a big thing to this issue. My proposal is below.
|
This is not so good for skate.js. |
Yes, what I requested was just an alternative way to type check JSX, not 'optionalized types`, which is a separate complex feature. |
Partial types, as proposed by @RyanCavanaugh in #11233, might well be able to model this. |
@aluanhaddad Partial and optionalized types are the same thing. Even though it sounds like overkill for this issue, it will work, however we'll need a way to tell the compiler that And if we need a new switch anyway, does its implementation really need to involve partial types if it can be done without them like @vvakame wrote? |
Now I am understood what @RyanCavanaugh and @aluanhaddad are said. We need good proposal. IMHO, If JSX.ElementAttributesProperty has callable property, Use the return type instead of the type passed as an argument for checking.
This issue is last 2 mile of SkateJS+TypeScript. (other 1 is #12488 ) |
Hm... abstract class Component {
/** A bogus type-system-only property. */
private __bogusProps: Partial<this>;
}
declare namespace JSX {
type Element = string;
interface ElementAttributesProperty {
__bogusProps: Partial<this>;
}
}
class FooComponent extends Component {
foo: number;
method() { }
}
// ta-da !
let z = <FooComponent foo={2}/>; |
@RyanCavanaugh It's been two years. Any progress on this front? We were hoping to enable JSX for Aurelia vNext but this issue is causing the compiler to be very unhappy with us. |
@EisenbergEffect Doesn't this solution work for you? |
One of the unique and important aspects of Aurelia's design is that it doesn't require using base classes for components. Components are plain classes. In fact, we discourage the use of inheritance and prefer guiding our community to use more compositional approaches. As such, even if the above did work, it wouldn't be an acceptable solution for us. That said, I've tried a few solutions that leverage the JSX namespace without inheritance and VS Code at least, doesn't seem to be affected at all in it's TS error reporting. It just doesn't work. I've been starting to wonder if there's a bug that was introduced in the last update... I need to experiment some more. It would be nice to have a real solution to this though. |
@EisenbergEffect It suddenly crossed my mind that we could extend interface Object {
/** A bogus type-system-only property. */
__bogusProps: Partial<this>;
}
declare namespace JSX {
type Element = string;
interface ElementAttributesProperty {
__bogusProps: any;
}
} But alas... TS adds the BTW, I didn't quite understand your "even if the above did work". It does work. |
Thanks for continuing to explore this @thorn0 I honestly can't remember if I tried the technique above or not. I know I tried a few things which didn't seem to work at least at one time. What I wanted to emphasize was that, either way, it's contrary to Aurelia's philosophy to force the use of a base class, so we wouldn't want to recommend this approach to our community as a best practice. @RyanCavanaugh What we really need is a way to declare that the element attributes are derived directly from the type itself. In other words the properties of the object are the attributes of the element. There's no special property involved. |
@EisenbergEffect Did you consider writing a design proposal? |
@EisenbergEffect that is supported already by declaring the type |
Here's my code: import { createElement } from './templating/create-element';
declare namespace JSX {
type Element = string;
interface ElementAttributesProperty {
}
}
class Foo {
public bar: string;
}
const view = () =>
<div>
<Foo bar="baz"></Foo>
</div>; I get the error |
@EisenbergEffect Because of the To make it global, use declare global {
namespace JSX {
type Element = string;
interface ElementAttributesProperty {
}
}
} But after that you're going to face my original issue: the compiler requires that all the non-optional members of the class (including methods and private members) be represented as attributes. |
Thanks @thorn0 ! I can confirm that exact behavior now. Here's my code: import { createElement } from './templating/create-element';
declare global {
namespace JSX {
type Element = string;
interface ElementAttributesProperty {
}
}
}
class Foo {
public bar: string = '';
public baz: number = 0;
}
const view = () =>
<div>
<Foo bar='test'></Foo>
</div>; @RyanCavanaugh This would be 100% valid in Aurelia but TS is complaining that the |
Hi, @vvakame , the optional property is not working with The typescript source code is here: Now, i want to turn off required properties check in TSX context , what should i do? |
I got it that how to turn off the required properties check in TSX context. The code is below: declare namespace JSX {
// ...
interface IntrinsicAttributes {
[attributeName: string]: any
}
// ...
} |
It's not documented, but currently, if the
JSX.ElementAttributesProperty
interface is declared empty,then the element attributes type becomes same as the element instance type. However, if the element instance type is a class, this leads to a situation where the compiler requires that all the members of the class be represented as attributes since they're not optional (and even cannot be marked as such as the class syntax doesn't allow optional members).
This prevents me from using JSX for type-checking Angular 1 templates (you can find my experiments in this area here).
What if we introduce some way to tell the compiler that not all the properties are required, but only some of them? E.g. those having a certain decorator?
A related issue: #5151
The text was updated successfully, but these errors were encountered: