function f(data:{a:string?; b:string?; c:string?}):{a:boolean; b:boolean; c:boolean}
local r={}
if data.a then r.a=true end
if data.b then r.b=true end
if data.c then r.c=true end
return r
end
local out=f({a="a",b=nil,c="c"})```
and if you change the signature to optional like the input `{a:boolean?; b:boolean?; c:boolean?}` you have to refine the types after you call it even though you can guarantee it exists in the output. so how do you do it? well, functions can have union types, and you have to make every permutation of the inputs and outputs: ```lua
export type Permutation9x9<Ai,Ao,Bi,Bo,Ci,Co,Di,Do,Ei,Eo,Fi,Fo,Gi,Go,Hi,Ho,Ii,Io> =
io<Ai&Bi&Ci&Di&Ei&Fi&Gi&Hi&Ii,Ao&Bo&Co&Do&Eo&Fo&Go&Ho&Io> &
io<Ai&Bi&Ci&Di&Ei&Fi&Gi&Hi,Ao&Bo&Co&Do&Eo&Fo&Go&Ho> &
io<Ai&Bi&Ci&Di&Ei&Fi&Gi&Ii,Ao&Bo&Co&Do&Eo&Fo&Go&Io> &
io<Ai&Bi&Ci&Di&Ei&Fi&Hi&Ii,Ao&Bo&Co&Do&Eo&Fo&Ho&Io> &
io<Ai&Bi&Ci&Di&Ei&Gi&Hi&Ii,Ao&Bo&Co&Do&Eo&Go&Ho&Io> &
io<Ai&Bi&Ci&Di&Fi&Gi&Hi&Ii,Ao&Bo&Co&Do&Fo&Go&Ho&Io> &
io<Ai&Bi&Ci&Ei&Fi&Gi&Hi&Ii,Ao&Bo&Co&Eo&Fo&Go&Ho&Io> &
io<Ai&Bi&Di&Ei&Fi&Gi&Hi&Ii,Ao&Bo&Do&Eo&Fo&Go&Ho&Io> &
io<Ai&Ci&Di&Ei&Fi&Gi&Hi&Ii,Ao&Co&Do&Eo&Fo&Go&Ho&Io> &
io<Bi&Ci&Di&Ei&Fi&Gi&Hi&Ii,Bo&Co&Do&Eo&Fo&Go&Ho&Io> &
io<Ai&Bi&Ci&Di&Ei&Fi&Gi,Ao&Bo&Co&Do&Eo&Fo&Go> &
io<Ai&Bi&Ci&Di&Ei&Fi&Hi,Ao&Bo&Co&Do&Eo&Fo&Ho> &
io<Ai&Bi&Ci&Di&Ei&Fi&Ii,Ao&Bo&Co&Do&Eo&Fo&Io> &
io<Ai&Bi&Ci&Di&Ei&Gi&Hi,Ao&Bo&Co&Do&Eo&Go&Ho> &