In M language, there is Type.ForRecord
function which can be used to create a record type dynamically.
// These two expressios are exchangeable
type [A = Int64.Type, optional B = text]
Type.ForRecord(
[
A = [Type = type number, Optional = false],
B = [Type = type text, Optional = true]
],
false
)
Using this, we are able to create a new record type based on an existing type with an additional field like below.
// These two expressions are exchangeable
type [A = Int64.Type, optional B = text, optional C = date]
let
existingType = [A = Int64.Type, optional B = text],
newFieldName = "C",
newFieldType = type date
in
Type.ForRecord(
Record.AddField(
Type.RecordFields(existingType),
newFieldName,
[Type = newFieldType, Optional = true]
),
false
)
Now, I am looking for a way to do a similar thing with table types. I want to be able to modify an existing table type adding a new column. The name and the type of the new column is dynamically determined in the runtime.
// I want this result
type table [A = Int64.Type, B = text, C = date]
// How can I create a new table type adding column `C = date`?
let
existingType = type table [A = Int64.Type, B = text],
newColumnName = "C",
newColumnType = type date
in
...
I was expecting there is a function like Type.ForTable
, but I could not find such. Is there any idea?
The trivial way to do this is as follows:
newType = type table [A = Int64.Type, B = text, newFieldName = newFieldType]
But that isn't going to work if your existingType
is dynamic.
If you keep your existingType
definition as a generic record (rather than a table), you can get the new table type by casting it to a table type after adding the new record field.
let
existingType = type /*no table here*/ [A = Int64.Type, B = text],
newFieldName = "C",
newFieldType = type date,
newType =
Type.ForRecord(
Record.AddField(
Type.RecordFields(existingType),
newFieldName,
[Type = newFieldType, Optional = false]
),
false
),
newTableType = type table newType
in
newTableType