Skip to content

[Bug]: getNativeElementProps is not type safe #29311

@bsunderhus

Description

@bsunderhus

getNativeElementProps definition allows anything ({}) to be provided as it's argument of properties to be filtered but it doesn't associate those properties with the return value. The result of that is that you can provide any wrong type of data as a property and it'll be converted to something valid.

A possible case would be of wrongly typed handlers, in the example below I am defining a root slot which is a div but wrongly introducing on it's props a onKeyDown handler that expects a HTMLFormElement as currentTarget:

import * as React from 'react'
import {getNativeElementProps, slot, UnknownSlotProps} from '@fluentui/react-utilities'

const props = {} as UnknownSlotProps

const root = slot.always(
    getNativeElementProps(props.as ?? 'div', {
    ...props,
    onKeyDown: (event: React.KeyboardEvent<HTMLFormElement>) => {
        event.currentTarget.submit() // 💣 This will explode in runtime, as this slot is a div, not a form
    },
    }),
    { elementType: 'div' },
)

Playground Link: Provided

No type errors are available in those cases! Since getNativeElementProps does not link what it receives to what it produces

export function getNativeElementProps<TAttributes extends React.HTMLAttributes<any>>(
  tagName: string,
  props: {},
  excludedPropNames?: string[],
//💣 here's the problem, TAttribute is completely disassociated from `props`,
// allowing anyone to pass anything as props `{}` and always have as return a well defined `React.HTMLAttributes`,
// even if it has mistakes on it.
): TAttributes { 
  const allowedPropNames = (tagName && nativeElementMap[tagName]) || htmlElementProperties;
  allowedPropNames.as = 1;

  return getNativeProps(props, allowedPropNames, excludedPropNames);
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions