diff --git a/packages/pinia-orm/src/model/Model.ts b/packages/pinia-orm/src/model/Model.ts index d7a45b67b..b7f8901ff 100644 --- a/packages/pinia-orm/src/model/Model.ts +++ b/packages/pinia-orm/src/model/Model.ts @@ -826,11 +826,18 @@ export class Model { if (cast && operation === 'get') { value = cast.get(value) } + // Apply the cast before the field is filled so the type check + // validates the casted value instead of the raw input. + if (cast && operation === 'set' && value !== undefined) { + value = options.action === 'update' ? cast.get(value) : cast.set(value) + } + let keyValue = this.$fillField(key, attr, value) if (mutator && typeof mutator !== 'function' && operation === 'set' && mutator.set) { keyValue = mutator.set(keyValue) } - if (cast && operation === 'set') { + // Values filled by the attribute default still need to pass the cast. + if (cast && operation === 'set' && value === undefined) { keyValue = options.action === 'update' ? cast.get(keyValue) : cast.set(keyValue) } diff --git a/packages/pinia-orm/tests/unit/model/Model_Casts_Number.spec.ts b/packages/pinia-orm/tests/unit/model/Model_Casts_Number.spec.ts index bb28bb388..50863739d 100644 --- a/packages/pinia-orm/tests/unit/model/Model_Casts_Number.spec.ts +++ b/packages/pinia-orm/tests/unit/model/Model_Casts_Number.spec.ts @@ -92,4 +92,34 @@ describe('unit/model/Model_Casts_Number', () => { expect(userRepo.find(1)?.count).toBe(444) }) + + it('should not warn about a wrong type when the cast converts the value on save', () => { + const warningSpy = vi.spyOn(console, 'warn') + warningSpy.mockClear() + + class User extends Model { + static entity = 'users' + + @Attr(0) id!: number + + @Cast(() => NumberCast) + @Num(null) + count!: number | null + } + + const userRepo = useRepo(User) + userRepo.save({ + id: 1, + count: '10191', + }) + + assertState({ + users: { + 1: { id: 1, count: 10191 }, + }, + }) + + expect(userRepo.find(1)?.count).toBe(10191) + expect(warningSpy).not.toHaveBeenCalled() + }) })