46
loading...
This website collects cookies to deliver better user experience
// .ts
type QueryUser = {
age: number
name: string
}
type SubscriptionUser = {
age: number
name: string
}
const logMyUser = ({ age, name }: QueryUser) => {
console.log(`Hi! I am ${name} of ${age} years old.`)
}
const subscriptionUser: SubscriptionUser = {
name: "John",
age: 30,
}
logMyUser(subscriptionUser)
// .res
type queryUser = {
name: string,
age: int,
}
type subscriptionUser = {
name: string,
age: int,
}
let logMyUser = ({name, age}: queryUser) => {
Js.log(`Hi! I am ${name} of ${age->Js.Int.toString} years old.`)
}
let subscriptionUser: subscriptionUser = {name: "John", age: 30}
logMyUser(subscriptionUser)
// ERROR:
// [E] Line 17, column 10:
// This has type: subscriptionUser
// Somewhere wanted: queryUser
somewhere
might be.This has type `x`
Somewhere wanted type `y`
Types for method `z` are incompatible
// Page.ts
import React, { useState, useEffect } from "react"
type QueryUser = {
name: string
age: number
}
type SubscriptionUser = {
name: string
age: number
}
type QueryResult = {
id: string
userData: QueryUser
}
type SubscriptionResult = {
id: string
userData: SubscriptionUser
}
// assume we have an array of users fetched from a GraphQL api
const someMagicWayToGetData = (): QueryResult[] => {
const users = [
{ id: "1", userData: { name: "John", age: 35 } },
{ id: "2", userData: { name: "Mary", age: 20 } },
{ id: "3", userData: { name: "Kate", age: 50 } },
]
return users
}
// and a graphQL subscription to push updates to our page
const someMagicWayToGetUpdates = (): SubscriptionResult => {
const updatedUser = {
id: "2",
userData: { name: "Mary Jane", age: 21 },
}
return updatedUser
}
const Page = () => {
const [
users,
setUsers
] = useState<QueryResult[]>(someMagicWayToGetData())
const updatedUser = someMagicWayToGetUpdates()
useEffect(() => {
const newUsers = users.map((user) => {
if (user.id === updatedUser.id) {
return {
...user,
userData: updatedUser.userData,
}
}
return user
})
setUsers(newUsers)
}, [updatedUser])
return (
<div>
<ul>
{users.map(({ id, userData: { name, age } }) => (
<li key={id}>
User: {name}; Age: {age}
</li>
))}
</ul>
</div>
)
}
export default Page
// .res
let newUsers = users->Js.Array2.map(user => {
if user.id == updatedUser.id {
{...user, userData: updatedUser.userData}
} else {
user
}
})
// Error:
// [E] Line 43, column 20:
// This has type: subscriptionUser
// Somewhere wanted: queryUser
// Page.res
type queryUser = {
name: string,
age: int,
}
type subscriptionUser = {
name: string,
age: int,
}
type queryResult = {id: string, userData: queryUser}
type subscriptionResult = {id: string, userData: subscriptionUser}
let someMagicWayToGetData: unit => array<queryResult> = () => {
let users: array<queryResult> = [
{id: "1", userData: {name: "John", age: 35}},
{id: "2", userData: {name: "Mary", age: 20}},
{id: "3", userData: {name: "Kate", age: 50}},
]
users
}
let someMagicWayToGetUpdates: unit => subscriptionResult = () => {
let updatedUser = {
id: "2",
userData: {name: "Mary Jane", age: 21},
}
updatedUser
}
@react.component
let default = () => {
let (users, setUsers) = React.useState(_ => someMagicWayToGetData())
let updatedUser = someMagicWayToGetUpdates()
React.useEffect1(() => {
let newUsers = users->Js.Array2.map(user => {
if user.id == updatedUser.id {
{
...user,
userData: {
name: updatedUser.userData.name,
age: updatedUser.userData.age,
},
}
} else {
user
}
})
setUsers(_ => newUsers)
None
}, [updatedUser])
<div>
<ul>
{users
->Js.Array2.map(({id, userData: {name, age}}) =>
<li key=id> {`User: ${name}; Age: ${age->Js.Int.toString}`->React.string} </li>
)
->React.array}
</ul>
</div>
}
// .res
type user = {
name: string,
age: int,
}
type userData = {
id: string,
userData: user,
}
type result =
| QueryResult(userData)
| SubscriptionResult(userData)
let users: array<result> = [
QueryResult({
id: "1",
userData: {name: "John", age: 35},
}),
QueryResult({
id: "2",
userData: {name: "Mary", age: 20},
}),
QueryResult({
id: "3",
userData: {name: "Kate", age: 50},
}),
]
let updatedUser: result = SubscriptionResult({
id: "2",
userData: {name: "Mary Jane", age: 21},
})
let newUsers = users->Js.Array2.reduce((allUsers, user) => {
switch (user, updatedUser) {
| (
QueryResult({id}),
SubscriptionResult({id: subscriptionId, userData: subscriptionUserData})
) if id == subscriptionId =>
allUsers->Js.Array2.concat([
QueryResult({
id: id,
userData: subscriptionUserData,
}),
])
| (QueryResult(user), _) => allUsers->Js.Array2.concat([QueryResult(user)])
| (_, _) => allUsers
}
}, [])