Improve type checking for metrics events (#2632)

zio/stable
Eric Bailey 2024-01-25 23:12:48 -06:00 committed by GitHub
parent bc502edae1
commit 157404132f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 37 deletions

View File

@ -6,7 +6,7 @@ import {sha256} from 'js-sha256'
import {Native} from 'sentry-expo' import {Native} from 'sentry-expo'
import {useSession, SessionAccount} from '#/state/session' import {useSession, SessionAccount} from '#/state/session'
import {TrackEvent, AnalyticsMethods} from './types' import {ScreenPropertiesMap, TrackPropertiesMap} from './types'
import {logger} from '#/logger' import {logger} from '#/logger'
type AppInfo = { type AppInfo = {
@ -29,20 +29,30 @@ function getClient(): SegmentClient {
return segmentClient return segmentClient
} }
export const track: TrackEvent = async (...args) => { export const track = async <E extends keyof TrackPropertiesMap>(
await getClient().track(...args) event: E,
properties?: TrackPropertiesMap[E],
) => {
await getClient().track(event, properties)
} }
export function useAnalytics(): AnalyticsMethods { export function useAnalytics() {
const {hasSession} = useSession() const {hasSession} = useSession()
return React.useMemo(() => { return React.useMemo(() => {
if (hasSession) { if (hasSession) {
return { return {
async screen(...args) { async screen<E extends keyof ScreenPropertiesMap>(
await getClient().screen(...args) event: E,
properties?: ScreenPropertiesMap[E],
) {
await getClient().screen(event, properties)
}, },
async track(...args) { async track<E extends keyof TrackPropertiesMap>(
await getClient().track(...args) event: E,
properties?: TrackPropertiesMap[E],
) {
await getClient().track(event, properties)
}, },
} }
} }

View File

@ -3,7 +3,7 @@ import {createClient} from '@segment/analytics-react'
import {sha256} from 'js-sha256' import {sha256} from 'js-sha256'
import {Browser} from 'sentry-expo' import {Browser} from 'sentry-expo'
import {TrackEvent, AnalyticsMethods} from './types' import {ScreenPropertiesMap, TrackPropertiesMap} from './types'
import {useSession, SessionAccount} from '#/state/session' import {useSession, SessionAccount} from '#/state/session'
import {logger} from '#/logger' import {logger} from '#/logger'
@ -29,20 +29,30 @@ function getClient(): SegmentClient {
return segmentClient return segmentClient
} }
export const track: TrackEvent = async (...args) => { export const track = async <E extends keyof TrackPropertiesMap>(
await getClient().track(...args) event: E,
properties?: TrackPropertiesMap[E],
) => {
await getClient().track(event, properties)
} }
export function useAnalytics(): AnalyticsMethods { export function useAnalytics() {
const {hasSession} = useSession() const {hasSession} = useSession()
return React.useMemo(() => { return React.useMemo(() => {
if (hasSession) { if (hasSession) {
return { return {
async screen(...args) { async screen<E extends keyof ScreenPropertiesMap>(
await getClient().screen(...args) event: E,
properties?: ScreenPropertiesMap[E],
) {
await getClient().screen(event, properties)
}, },
async track(...args) { async track<E extends keyof TrackPropertiesMap>(
await getClient().track(...args) event: E,
properties?: TrackPropertiesMap[E],
) {
await getClient().track(event, properties)
}, },
} }
} }

View File

@ -1,14 +1,4 @@
export type TrackEvent = ( export type TrackPropertiesMap = {
event: keyof TrackPropertiesMap,
properties?: TrackPropertiesMap[keyof TrackPropertiesMap],
) => Promise<void>
export type ScreenEvent = (
name: keyof ScreenPropertiesMap,
properties?: ScreenPropertiesMap[keyof ScreenPropertiesMap],
) => Promise<void>
interface TrackPropertiesMap {
// LOGIN / SIGN UP events // LOGIN / SIGN UP events
'Sign In': {resumedSession: boolean} // CAN BE SERVER 'Sign In': {resumedSession: boolean} // CAN BE SERVER
'Create Account': {} // CAN BE SERVER 'Create Account': {} // CAN BE SERVER
@ -16,7 +6,7 @@ interface TrackPropertiesMap {
'Signin:PressedForgotPassword': {} 'Signin:PressedForgotPassword': {}
'Signin:PressedSelectService': {} 'Signin:PressedSelectService': {}
// COMPOSER / CREATE POST events // COMPOSER / CREATE POST events
'Create Post': {imageCount: string} // CAN BE SERVER 'Create Post': {imageCount: string | number} // CAN BE SERVER
'Composer:PastedPhotos': {} 'Composer:PastedPhotos': {}
'Composer:CameraOpened': {} 'Composer:CameraOpened': {}
'Composer:GalleryOpened': {} 'Composer:GalleryOpened': {}
@ -108,15 +98,15 @@ interface TrackPropertiesMap {
'CustomFeed:Share': {} 'CustomFeed:Share': {}
'CustomFeed:Pin': { 'CustomFeed:Pin': {
uri: string uri: string
name: string name?: string
} }
'CustomFeed:Unpin': { 'CustomFeed:Unpin': {
uri: string uri: string
name: string name?: string
} }
'CustomFeed:Reorder': { 'CustomFeed:Reorder': {
uri: string uri: string
name: string name?: string
index: number index: number
} }
'CustomFeed:LoadMore': {} 'CustomFeed:LoadMore': {}
@ -165,7 +155,7 @@ interface TrackPropertiesMap {
'OnboardingV2:Skip': {} 'OnboardingV2:Skip': {}
} }
interface ScreenPropertiesMap { export type ScreenPropertiesMap = {
Login: {} Login: {}
CreateAccount: {} CreateAccount: {}
'Choose Account': {} 'Choose Account': {}
@ -184,8 +174,3 @@ interface ScreenPropertiesMap {
MutedAccounts: {} MutedAccounts: {}
SavedFeeds: {} SavedFeeds: {}
} }
export type AnalyticsMethods = {
screen: ScreenEvent
track: TrackEvent
}