Attribute type checking

Attribute type checking

The first step to type checking attributes is to determine the element attributes type. This is slightly different between intrinsic and value-based elements.

For intrinsic elements, it is the type of the property on JSX.IntrinsicElements

declare namespace JSX {
  interface IntrinsicElements {
  foo: { bar?: boolean }
  }
}

// element attributes type for 'foo' is '{bar?: boolean}'
<foo bar />;

For value-based elements, it is a bit more complex. It is determined by the type of a property on the element instance type that was previously determined. Which property to use is determined by JSX.ElementAttributesProperty. It should be declared with a single property. The name of that property is then used.

declare namespace JSX {
  interface ElementAttributesProperty {
  props; // specify the property name to use
  }
}

class MyComponent {
  // specify the property on the element instance type
  props: {
  foo?: string;
  }
}

// element attributes type for 'MyComponent' is '{foo?: string}'
<MyComponent foo="bar" />

The element attribute type is used to type check the attributes in the JSX. Optional and required properties are supported.

declare namespace JSX {
  interface IntrinsicElements {
  foo: { requiredProp: string; optionalProp?: number }
  }
}

<foo requiredProp="bar" />; // ok
<foo requiredProp="bar" optionalProp={0} />; // ok
<foo />; // error, requiredProp is missing
<foo requiredProp={0} />; // error, requiredProp should be a string
<foo requiredProp="bar" unknownProp />; // error, unknownProp does not exist
<foo requiredProp="bar" some-unknown-prop />; // ok, because 'some-unknown-prop' is not a valid identifier

Note: If an attribute name is not a valid JS identifier (like a data-* attribute), it is not considered to be an error if it is not found in the element attributes type.

The spread operator also works:

var props = { requiredProp: "bar" };
<foo {...props} />; // ok

var badProps = {};
<foo {...badProps} />; // error
doc_TypeScript
2016-10-04 19:25:02
Comments
Leave a Comment

Please login to continue.