diff --git a/serde/de.py b/serde/de.py
index 5451cf6..5674f0a 100644
--- a/serde/de.py
+++ b/serde/de.py
@@ -438,7 +438,10 @@ def from_obj(c: Type[T], o: Any, named: bool, reuse_instances: Optional[bool]) -
     try:
         thisfunc = functools.partial(from_obj, named=named, reuse_instances=reuse_instances)
         if is_dataclass_without_de(c):
-            deserialize(c)
+            # Do not automatically implement beartype if dataclass without serde decorator
+            # is passed, because it is surprising for users
+            # See https://github.com/yukinarit/pyserde/issues/480
+            deserialize(c, type_check=disabled)
             res = deserializable_to_obj(c)
         elif is_deserializable(c):
             res = deserializable_to_obj(c)
diff --git a/serde/se.py b/serde/se.py
index eca1dcc..a69544f 100644
--- a/serde/se.py
+++ b/serde/se.py
@@ -366,7 +366,10 @@ def to_obj(
         if o is None:
             return None
         if is_dataclass_without_se(o):
-            serialize(type(o))
+            # Do not automatically implement beartype if dataclass without serde decorator
+            # is passed, because it is surprising for users
+            # See https://github.com/yukinarit/pyserde/issues/480
+            serialize(type(o), type_check=disabled)
             return serializable_to_obj(o)
         elif is_serializable(o):
             return serializable_to_obj(o)

diff --git a/tests/test_type_check.py b/tests/test_type_check.py
index 86caad6..9f3dd63 100644
--- a/tests/test_type_check.py
+++ b/tests/test_type_check.py
@@ -1,3 +1,4 @@
+from dataclasses import dataclass
 import datetime
 import pathlib
 from beartype.roar import BeartypeCallHintViolation
@@ -15,6 +16,7 @@ from beartype.typing import (
 import pytest
 
 import serde
+import serde.json
 
 from . import data
 
@@ -100,6 +102,18 @@ def test_type_check_strict(T: Any, data: Any, exc: bool) -> None:
         serde.from_dict(C, d)
 
 
+def test_type_check_disabled_for_dataclass_without_serde() -> None:
+    @dataclass
+    class Foo:
+        value: int
+
+    f = Foo("100")  # type: ignore
+    data = serde.json.to_json(f)
+    assert f == serde.json.from_json(Foo, data)
+
+    f = Foo("100")  # type: ignore
+
+
 def test_uncoercible() -> None:
     @serde.serde(type_check=serde.coerce)
     class Foo:

Bear type checking "leaks" to classes without the @serde decorator
Hi,

With update 0.14, it seems that bear type checking is being applied to classes passed as arguments to `serde.json.to_json`, even if they do not have the `@serde` decorator applied to them.

In general I prefer to not use the `@serde` decorator in my model classes, instead using `serde` only at the I/O layer with the `serde.json.from_json` and `serde.json.to_json` functions.

However seems like after calling `to_json` into a dataclass without the `@serde` decorator, bear type checking is now applied to that class from that point onward, which is surprising.

Example:

```python
from dataclasses import dataclass

import serde.json


@dataclass
class Foo:
    value: int


# This passes.
f = Foo("100")

data = serde.json.to_json(f, cls=Foo)

# After to_json(), this starts to fail with:
# beartype.roar.BeartypeCallHintParamViolation: Method __main__.Foo.__init__() parameter value='100' violates type hint <class 'int'>, as str '100' not instance of int.
f = Foo("100")
```

This is surprising to the user, even more so because model classes start to validate their types *after* some I/O has been performed, which might happen at different points in the application.

A workaround for now is to decorate `Foo` with `@serde(type_check=disabled)`, however this is not ideal given the functions `to_json` and `from_json` do not convey that they might change the runtime behavior of the class being passed as parameter.


> [!Note]
> This example is simplified, but in my code it was more complex, where I had an attribute declared as `tuple[int, ...]` but would accept any `Sequence[int]` at runtime, being converted to `tuple[int, ...]` during `__post_init__` to ensure the constructed object would have the correct runtime type. The reason for this is that the `Sequence[int]` comes from an external source, and sometimes would be provided as `list[int]` or `tuple[int, ...]`.
tests/test_type_check.py::test_type_check_disabled_for_dataclass_without_serde
tests/test_type_check.py::test_type_check_strict[int-10-False] tests/test_type_check.py::test_type_check_strict[int-10.0-True] tests/test_type_check.py::test_type_check_strict[int-10-True] tests/test_type_check.py::test_type_check_strict[int-True-False] tests/test_type_check.py::test_type_check_strict[float-10-True0] tests/test_type_check.py::test_type_check_strict[float-10.0-False] tests/test_type_check.py::test_type_check_strict[float-10-True1] tests/test_type_check.py::test_type_check_strict[float-True-True] tests/test_type_check.py::test_type_check_strict[str-10-True] tests/test_type_check.py::test_type_check_strict[str-10.0-True] tests/test_type_check.py::test_type_check_strict[str-10-False] tests/test_type_check.py::test_type_check_strict[str-True-True] tests/test_type_check.py::test_type_check_strict[bool-10-True0] tests/test_type_check.py::test_type_check_strict[bool-10.0-True] tests/test_type_check.py::test_type_check_strict[bool-10-True1] tests/test_type_check.py::test_type_check_strict[bool-True-False] tests/test_type_check.py::test_type_check_strict[list-data16-False] tests/test_type_check.py::test_type_check_strict[list-data17-True] tests/test_type_check.py::test_type_check_strict[list-data18-False] tests/test_type_check.py::test_type_check_strict[list-data19-True] tests/test_type_check.py::test_type_check_strict[list-data20-True] tests/test_type_check.py::test_type_check_strict[list-data21-False] tests/test_type_check.py::test_type_check_strict[list-data22-True] tests/test_type_check.py::test_type_check_strict[list-data23-False] tests/test_type_check.py::test_type_check_strict[list-data24-True] tests/test_type_check.py::test_type_check_strict[list-data25-False] tests/test_type_check.py::test_type_check_strict[list-data26-True] tests/test_type_check.py::test_type_check_strict[list-data27-False] tests/test_type_check.py::test_type_check_strict[dict-data28-False] tests/test_type_check.py::test_type_check_strict[dict-data30-False] tests/test_type_check.py::test_type_check_strict[dict-data31-True] tests/test_type_check.py::test_type_check_strict[set-data32-False] tests/test_type_check.py::test_type_check_strict[set-data33-False] tests/test_type_check.py::test_type_check_strict[set-data34-True] tests/test_type_check.py::test_type_check_strict[tuple-data35-False] tests/test_type_check.py::test_type_check_strict[tuple-data36-True] tests/test_type_check.py::test_type_check_strict[tuple-data37-False] tests/test_type_check.py::test_type_check_strict[tuple-data38-True] tests/test_type_check.py::test_type_check_strict[tuple-data39-False] tests/test_type_check.py::test_type_check_strict[tuple-data40-True] tests/test_type_check.py::test_type_check_strict[tuple-data41-False] tests/test_type_check.py::test_type_check_strict[tuple-data42-False] tests/test_type_check.py::test_type_check_strict[E-E.S-False] tests/test_type_check.py::test_type_check_strict[E-IE.V0-True] tests/test_type_check.py::test_type_check_strict[T45-10-False] tests/test_type_check.py::test_type_check_strict[T46-foo-False] tests/test_type_check.py::test_type_check_strict[T47-10.0-True] tests/test_type_check.py::test_type_check_strict[T48-data48-False] tests/test_type_check.py::test_type_check_strict[date-data49-False] tests/test_type_check.py::test_type_check_strict[Path-data50-False] tests/test_type_check.py::test_type_check_strict[Path-foo-True] tests/test_type_check.py::test_uncoercible tests/test_type_check.py::test_coerce