TypeScript Error (ts2345) when trying to collect property names in array - Stack Overflow
The following updated simplified code illustrates the problem:
type BaseCol<TCol> = TCol & {
syncProps?: Exclude<keyof BaseCol<TCol>, "syncProps">[];
width?: number;
text: string;
}
function createProperty<
TColumn extends BaseCol<ExtraProps>,
ExtraProps
>(column: TColumn, prop: Exclude<keyof TColumn, "syncProps">) {
const x = column[prop];
column.syncProps ??= [];
column.syncProps.push(prop); // <--- TS2345 Error.
}
createProperty({
a: 1,
b: 2,
width: 1,
text: 'ABC'
}, 'a'); // <--- Intellisense works.
The base type BaseCol<TCol>
is the type that consumers of a Svelte component use to define their list of columns. The TCol
type parameter is intended to extend the properties of their columns to satisfy their business need.
On the other hand, the createProperty
function intends to create a "synchronizable" version of any of the properties (implementation not shown), and then record the property name in the column's syncProps
property.
From the definition above, the second parameter to createProperty
is "all properties of the column, except the control properties" (of which I only show one, syncProps
). Consequently, syncProps
itself is typed the exact same way.
NOTE: The original code snippet in this question did not define the second type parameter (ExtraProps
) in createProperty
and instead the first one extended from BaseCol<Record<string, any>>
. This is why the first comment refers to this (now gone) fact.
Playground Link
An example use-case:
type MyColumn = BaseCol<{ a: string; b: number; }>;
const cols: MyColumn[] = [
...
];
createProperty(cols[3], 'width');
The following updated simplified code illustrates the problem:
type BaseCol<TCol> = TCol & {
syncProps?: Exclude<keyof BaseCol<TCol>, "syncProps">[];
width?: number;
text: string;
}
function createProperty<
TColumn extends BaseCol<ExtraProps>,
ExtraProps
>(column: TColumn, prop: Exclude<keyof TColumn, "syncProps">) {
const x = column[prop];
column.syncProps ??= [];
column.syncProps.push(prop); // <--- TS2345 Error.
}
createProperty({
a: 1,
b: 2,
width: 1,
text: 'ABC'
}, 'a'); // <--- Intellisense works.
The base type BaseCol<TCol>
is the type that consumers of a Svelte component use to define their list of columns. The TCol
type parameter is intended to extend the properties of their columns to satisfy their business need.
On the other hand, the createProperty
function intends to create a "synchronizable" version of any of the properties (implementation not shown), and then record the property name in the column's syncProps
property.
From the definition above, the second parameter to createProperty
is "all properties of the column, except the control properties" (of which I only show one, syncProps
). Consequently, syncProps
itself is typed the exact same way.
NOTE: The original code snippet in this question did not define the second type parameter (ExtraProps
) in createProperty
and instead the first one extended from BaseCol<Record<string, any>>
. This is why the first comment refers to this (now gone) fact.
Playground Link
An example use-case:
type MyColumn = BaseCol<{ a: string; b: number; }>;
const cols: MyColumn[] = [
...
];
createProperty(cols[3], 'width');
Share
Improve this question
edited 12 hours ago
José Ramírez
asked 15 hours ago
José RamírezJosé Ramírez
2,2708 silver badges19 bronze badges
7
|
Show 2 more comments
1 Answer
Reset to default -1Make sure syncProps is initialized properly to avoid issues,
function createProperty<T extends Record<string, any>>(
column: BaseCol<T>,
prop: keyof T
) {
const x = column[prop];
if (!column.syncProps) {
column.syncProps = [];
}
column.syncProps.push(prop as keyof T);
}
createProperty({ a: 1, b: 2 }, 'b');
- 百度推出智能云云手机
- 微信支付和支付宝口水战开打!
- 三问凡客“毁三观”
- 鲍尔默:未来5至10年微软将不再像一家软件公司
- Why is my openGL render failing, Python OpenGL - Stack Overflow
- unity game engine - After commit to git, all gameobjects loose their assets - Stack Overflow
- csv - How to Handle Clob Data Type in Excel When Exporting Data From DB2 Database - Stack Overflow
- swift - How to Add .mlmodel File to Xcode App Playgrounds (.swiftpm) Project? - Stack Overflow
- swiftui - Swift Mocking a throwing function - Stack Overflow
- How to configure PhpStorm to work with Node.js and ESLint inside a running Docker container? - Stack Overflow
- python - Windows java.io.EOFException error when trying to show spark dataframe - Stack Overflow
- imagemagick - How to add annotations in Right-To-Left (RTL) languages (like Arabic and Persian) to images using R's magi
- python - Change one pair of vertices to create a cycle in an oriented graph - Stack Overflow
- flutter - How to adjust code formatting when formatting the document - Stack Overflow
- javascript - Why does the iterator close after a break in a for...of loop? - Stack Overflow
- algorithmic trading - Why is my python script working sometimes but not others? There seems to be a delay for it to work - Stack
- Is it possible to determine if the Julia JIT will return a heap allocated or stack allocated return value from a function call?
BaseCol<Record<string, any>>
is essentiallyRecord<string, any>
, andTColumn extends BaseCol<Record<string, any>>
doesn't constrainTColumn
to lack any particular key, such as asymbol
-valued one as shown in this playground link. You might have meant something different, but it's not what you're doing. It looks more like you need a recursive constraint like this playground link shows. Does that fully address the question? If so I'll write an answer explaining; if not, what's missing? – jcalz Commented 14 hours agoBaseCol<T>
is to allow consumers to add their own propreties to the definition of column they are creating. I can't see how I can use your recursive solution with my use case. Any ideas? – José Ramírez Commented 14 hours agoBaseCol
. It is how users define their list of columns.type MyColumn = BaseCol<{ a: number; } >;
– José Ramírez Commented 14 hours agoBaseCol
is not really sustainable. It's probably a dozen properties. – José Ramírez Commented 14 hours agoBaseCol
when definingT
in the function. The minimal repro shows onlysyncProps
, but it's a lot more properties. – José Ramírez Commented 13 hours ago