Description
π Search Terms
function, interface, augment, parentheses, inconsistent
π Version & Regression Information
- This is the behavior in every version I tried (all the way down to 3.3.3), and I reviewed the FAQ for entries about pretty much everything.
β― Playground Link
π» Code
declare global {
interface Function {
test?: string;
}
}
const TestFunc1 = function () {};
const TestFunc2 = (function () {});
function TestFunc3() {};
const TestArrowFunc1 = () => {};
const TestArrowFunc2 = (() => {});
TestFunc1.test = 1;
TestFunc2.test = 1;
TestFunc3.test = 1;
TestArrowFunc1.test = 1;
TestArrowFunc2.test = 1;
export {};
π Actual behavior
Only TestFunc2 and TestArrowFunc2 (the ones with ()
) are flagged as errors. All other cases are perfectly fine according to TypeScript.
π Expected behavior
All five of the .test = 1
lines should be flagged as errors, since 1
is not compatible with string | undefined
.
Additional information about the issue
I've only found this issue with properties on functions. Others (String, Number) work correctly in all cases, and even Function works correctly when the value is wrapped with ()
- but wrapping it in parentheses doesn't seem to have any semantic differences here.
My use case is trying to augment functions (specifically React components) in a massive codebase while enforcing types on the metadata being passed.
const Component = () => {};
Component.__metadata = metadata; // Function has the type so I don't have to cast or check!
Because of this bug, I have to use this instead:
import type { Metadata } from 'path/to/metadata/type';
const Component = () => {};
Component.__metadata = metadata satisfies Metadata as Metadata;
which is poor DX on three fronts (frustrating to read/write, appears redundant but is needed, and introduces a required import on every use).
Looked at: