Why can't some of the properties on the HTMLScriptElement be assigned to in TypeScript?

Viewed 123

I'm using TypeScript and React. I have a simple function which should copy script attributes from one to another:

type MutableScriptProperties = Pick<
  HTMLScriptElement,
  'async' | 'crossOrigin' | 'defer' | 'integrity' | 'noModule' | 'referrerPolicy' | 'type' | 'nonce'
>;

type Values<T extends object> = T[keyof T];

type MutableScriptKey = keyof MutableScriptProperties;

type MutableScriptValue = Values<MutableScriptProperties>;

const scriptPropertiesToClone: MutableScriptKey[] = [
  'async',
  'crossOrigin',
  'defer',
  'integrity',
  'noModule',
  'nonce',
  'referrerPolicy',
  'type',
];

function cloneScriptProperties(source: HTMLScriptElement, target: HTMLScriptElement): HTMLScriptElement {
  scriptPropertiesToClone.forEach((propKey) => {
    const sourceValue = source[propKey] as MutableScriptValue;

    if (sourceValue !== undefined) {
       target[propKey] = sourceValue; // this line throws an error
    }
  });
  return target;
}

On the line marked with a comment, I'm getting following error:

Type 'string | boolean | null' is not assignable to type 'never'.
  Type 'null' is not assignable to type 'never'.ts(2322)

Is there any reason why any of these the HTMLScriptTag props would return or be marked as never? What is the correct solution that doesn't involve casting?

1 Answers

For some reason target[propKey] is inferred to never. I don't have actual solution but rather workaround (that involves casting)

   (target[propKey] as unknown as MutableScriptValue) = sourceValue 
Related