Skip to content
AgileLogics
6 min read

Type Providers

Prerequisites: Projects and NuGet packages

A type provider generates types at compile time from an external source — a sample CSV or JSON file, a database schema, a web API description. You get autocompletion and type checking for data whose structure lives outside your code.

The best-known collection is FSharp.Data, with providers for CSV, JSON, XML, and HTML.

JSON provider

// illustrative: downloads FSharp.Data on first run
#r "nuget: FSharp.Data"
open FSharp.Data

type Weather = JsonProvider<"""
  { "city": "Oslo", "temperature": 3.5, "conditions": ["cloudy", "windy"] }
""">

let reading = Weather.Parse """
  { "city": "Lisbon", "temperature": 18.2, "conditions": ["sunny"] }
"""

printfn "%s: %.1f C" reading.City reading.Temperature
printfn "%A" reading.Conditions
Lisbon: 18.2 C
[|"sunny"|]

From the sample, the provider inferred a type with City: string, Temperature: decimal, and Conditions: string[]. Mistype reading.Temprature and you get a compile error, not a runtime surprise. The sample can also be a file path or a URL.

CSV provider

// illustrative: downloads FSharp.Data on first run
#r "nuget: FSharp.Data"
open FSharp.Data

type Sales = CsvProvider<"region,product,amount\nNorth,Tea,120\n">

let data =
    Sales.ParseRows "North,Tea,120\nSouth,Coffee,340\nNorth,Coffee,90"

data
|> Array.groupBy _.Region
|> Array.iter (fun (region, rows) ->
    printfn "%s: %d" region (rows |> Array.sumBy _.Amount))
North: 210
South: 340

Columns become typed properties (Amount is an int, inferred from the sample). For real files, use Sales.Load "sales.csv".

Other providers

  • SQLProvider and FSharp.Data.SqlClient — typed SQL queries checked against a live database schema at compile time.
  • SwaggerProvider — typed clients for OpenAPI/Swagger web APIs.
  • FSharp.Data.GraphQL — typed GraphQL clients.

Trade-offs

  • Providers that connect to a database or URL at compile time need that source available on every build machine (including CI) — or a cached schema file.
  • Keep samples in the repository so builds are reproducible.
  • Type providers are an F#-only feature: C# code can't use them directly, but it can use the resulting types if you expose them through normal records.