As @s952163 points out, it looks like you're attempting to read data from a database, in which case there are better options available than trying to do it yourself. Still, just to sketch out a possible solution if taking the OP at face value, here's one way to go about it.
Since the types listed aren't .NET types, perhaps it's better to define a custom type to hold such values:
open System
type DbType = NVarChar of string | DT of DateTime
You can add more cases to DbType if you'd like.
Using active patterns, you can write a function to convert a single candidate:
// string * string -> string option
let (|NVarChar|_|) = function
| "nvarchar", (x : string) -> Some x
| _ -> None
// string * string -> DateTime option
let (|DT|_|) (typeHint, value) =
match (typeHint, DateTime.TryParse value) with
| "date", (true, dt) -> Some dt
| _ -> None
// string * string -> DbType option
let convertPair = function
| NVarChar x -> Some (NVarChar x)
| DT x -> Some (DT x)
| _ -> None
The use of active patterns isn't strictly necessary, but I thought it enabled me to decompose the problem in a good way.
Now you can declare a list of types and one of values, zip them together to get a list of interpreted values:
> let types = ["nvarchar"; "nvarchar"; "date"; "nvarchar"];;
val types : string list = ["nvarchar"; "nvarchar"; "date"; "nvarchar"]
> let values = ["Jackson"; "Sentzke"; "1991-04-19T00:00:00"; "Jackson Sentske"];;
val values : string list =
["Jackson"; "Sentzke"; "1991-04-19T00:00:00"; "Jackson Sentske"]
> let converted = List.zip types values |> List.choose convertPair;;
val converted : DbType list =
[NVarChar "Jackson"; NVarChar "Sentzke"; DT 19.04.1991 00:00:00;
NVarChar "Jackson Sentske"]
Note that both types and values have the type string list. In the OP, they were (string * string * string * string) list, which I assume was a mistake.