I have an F# Record type
type MyType = {
Name : string
Description : string option
}
I'd like to get two arrays, one containing the names of the required properties and one containing the optional properties. How can I do this?
I have an F# Record type
type MyType = {
Name : string
Description : string option
}
I'd like to get two arrays, one containing the names of the required properties and one containing the optional properties. How can I do this?
open System.Reflection
/// inspired by https://stackoverflow.com/questions/20696262/reflection-to-find-out-if-property-is-of-option-type
let isOption (p : PropertyInfo) =
p.PropertyType.IsGenericType &&
p.PropertyType.GetGenericTypeDefinition() = typedefof<Option<_>>
/// required and optional property names of a type 'T - in that order
/// inspired by https://stackoverflow.com/questions/14221233/in-f-how-to-pass-a-type-name-as-a-function-parameter
/// inspired by https://stackoverflow.com/questions/59421595/is-there-a-way-to-get-record-fields-by-string-in-f
let requiredAndOptionalPropertiesOf<'T> =
let optionals, requireds = typeof<'T>.GetProperties() |> Array.partition isOption
let getNames (properties : PropertyInfo[]) = properties |> Array.map (fun f -> f.Name)
(getNames requireds, getNames optionals)
Here is an alternative answer that takes into account the comment by @Asti:
open System.Reflection
let isOption (p : PropertyInfo) =
p.PropertyType.IsGenericType &&
p.PropertyType.GetGenericTypeDefinition() = typedefof<Option<_>>
let requiredAndOptionalPropertiesOf<'T> =
let optionals, requireds = FSharp.Reflection.FSharpType.GetRecordFields typeof<'T> |> Array.partition isOption
let getNames (properties : PropertyInfo[]) = properties |> Array.map (fun f -> f.Name)
(getNames requireds, getNames optionals)