#How to determine object type by propery.startsWith()?
23 messages · Page 1 of 1 (latest)
Preview:```ts
type Image = {
name: image/${string}
width: 123
}
type Video = {
name: video/${string}
}
type Media = Image | Video
const a = {} as Media
if (a.name.startsWith("image/")) {
console.log(a.width)
}```
i don't think template strings can be used as discriminators
Why this works, but startsWith doesn't :/
huh, guess im wrong
startswith just doesn't narrow i guess
function startsWith<const T extends string>(str: string, substr: T): str is `${T}${string}` {
return str.startsWith(substr);
}
declare const x: { type: `image/${string}`, width: number } | { type: `video/${string}` }
if (startsWith(x.type, "image")) {
x
//^?
x.type
// ^?
}
!ts
!ts

!ts
function startsWith<const T extends string>(str: string, substr: T): str is `${T}${string}` {
return str.startsWith(substr);
}
declare const x: { type: `image/${string}`, width: number } | { type: `video/${string}` }
if (startsWith(x.type, "image")) {
x
//^? - const x: {
// type: `image/${string}`;
// width: number;
//} | {
// type: `video/${string}`;
//}
x.type
// ^? - (property) type: `image/${string}`
}
idk im on mobile right now so im not in a position to really thoroughly investigate this
That should work @calm fossil but I was wondering about native support
that doesn't work, though? check the type of x in the last code sample
it seems like narrowing the discriminated union itself doesn't happen here, but i'm not totally sure why
if by "native support" you mean augmenting the lib.d.ts type for startsWith, i think this would be safe/correct (but please make sure i didn't overlook something):
Preview:ts interface String { startsWith<P extends string>( searchString: P, position?: 0 | undefined ): this is `${P}${string}` startsWith( searchString: string, position?: number | undefined ): boolean } ...
but notice that it still doesn't narrow a the way you want
even this super-simple case doesn't work:
declare const isA: (value: string) => value is 'a'
declare const thing: { name: 'a', x: 1 } | { name: 'b', x: 2 }
if (isA(thing.name)) {
thing.x
// ^? - (property) x: 1 | 2
}